0

How do I give a parameter a list of values it is allowed to be passed as? Here is an example function:

void GamePiece::Rotate(int z){
    int x, y;
    for(int i = 0; i < 4; i++){
        x = pieceRectangles_[i].getPosition().y * z;
        y = pieceRectangles_[i].getPosition().x;
    }
}

I want z to be either 1 or negative 1. Besides if statements, how do I ensure this?

jburn7
  • 115
  • 1
  • 3
  • 14
  • I don't understand your question – taocp Sep 30 '14 at 18:17
  • If you want compile time verification, use two functions (RotatePositive, RotateNegative) - You might wrap that in a template –  Sep 30 '14 at 18:23

4 Answers4

3

You can use an actual enum class instead of passing the value by int.

enum class ERotation { eCW = 1, eCCW = -1 };

Then your function would be

void GamePiece::Rotate(ERotation const& z){
    // ...
}

Note though, if you use a enum like this, you cannot multiply z by your positions, because there is no implicit conversion to int. So you'd have to say

const int rotation = (z == ERotation::eCW) ? 1 : -1;

Or as @rici mentioned you can explicitly cast the enum value

const int rotation = int(z);

Using enum class is typesafe and will not allow a value outside the enumeration to be passed. This is also more extensible than bool since you can have many values, instead of two.

Cory Kramer
  • 98,167
  • 13
  • 130
  • 181
  • You can explicitly cast to int. Also, the enum is typesafe but not exactly value-safe since you can explicitly cast from int, as well. http://coliru.stacked-crooked.com/a/10a04b2baef64a3e – rici Sep 30 '14 at 18:32
  • @rici I didn't know that. That's definitely interesting. Any idea why they allow you to do `Rotation(42)` if that's not one of the enumerated values? – Cory Kramer Sep 30 '14 at 18:34
  • I found a thorough discussion of [that topic here](http://stackoverflow.com/questions/18195312/what-happens-if-you-static-cast-invalid-value-to-enum-class) – Cory Kramer Sep 30 '14 at 18:44
  • 2
    @Cyber: the compiler can't - in general - know what the intended enumeration values are, as enums have often been used (albeit more so in C APIs) as values to be combined and tested using e.g. bitwise operations. Still, in C++03 there's a formula for finding the Standard-guaranteed min and max values the enum can store, so it's not necessarily just "any int", while in C++11 you can optionally specify a particular underlying integral type which affects the values that can be stored. – Tony Delroy Sep 30 '14 at 18:44
1

Use boolean instead of int:

void GamePiece::Rotate(bool positive){
    int x, y;
    for(int i = 0; i < 4; i++){
        x = pieceRectangles_[i].getPosition().y * ( positive ? 1 : -1 );
        y = pieceRectangles_[i].getPosition().x;
    }
}

You probably should call that parameter something like clockwise, but I do not know if clockwise is +1 or -1 in your system.

Slava
  • 40,641
  • 1
  • 38
  • 81
1

It appears to me you are doing a 90′ degree rotation in 2D around a virtual normal (axis) in a positive or negative Z direction:

#include <iostream>

struct Point
{
    int x;
    int y;

    Point(int x, int y)
    :   x(x), y(y)
    {}
};

struct VirtualNormalZ
{
    int value;
    VirtualNormalZ(int value)
    :   value(0 <= value ? 1 : -1)
    {}
};

// CCW is positive
Point Rotate90Degrees(const Point p, const VirtualNormalZ& normal)
{
    return Point(p.y * -normal.value, p.x * normal.value);
}

int main()
{
    VirtualNormalZ positive_normal(123);
    Point p(1, 0);
    std::cout << "Positive:\n";
    for(unsigned i = 0; i < 4; ++i)
    {
        std::cout << p.x << ", " << p.y << '\n';
        p = Rotate90Degrees(p, positive_normal);
    }
    VirtualNormalZ negative_normal(-123);
    std::cout << "Negative:\n";
    for(unsigned i = 0; i < 4; ++i)
    {
        std::cout << p.x << ", " << p.y << '\n';
        p = Rotate90Degrees(p, negative_normal);
    }
}
0

Ask for a boolean or an enumerator instead, and translate this to 1 or -1 when you need it.

Lightness Races in Orbit
  • 358,771
  • 68
  • 593
  • 989