0

我有很多enum类型,像这样:

enum Color {COLOR_RED = 0, COLOR_GREEN = 1, COLOR_BLUE = 2, COLOR_NUM};
enum Direction {DIRECTION_FORWARD, DIRECTION_BACKWARD, DIRECTION_NUM};
enum Choice {CHOICE_THIS, CHOICE_THAT, CHOICE_NUM}; // i've just made it up

在我的代码中的许多地方,我想对所有可能的值进行循环;我希望它看起来像这样:

for (Color c = COLOR_RED; c != COLOR_NUM; ++c)
{
    ...
}

为此,我operator++一起定义Color

enum Color {COLOR_RED = 0, COLOR_GREEN = 1, COLOR_BLUE = 2, COLOR_NUM};

inline Color& operator++(Color& c)
{
    c = static_cast<Color>(c + 1);
    return c;
}

operator++我还为习惯于使用i++而不是编码循环的人定义后缀++i

inline Color operator++(Color& c, int)
{
    Color r = c;
    c = static_cast<Color>(c + 1);
    return r;
}

我想知道如何使用模板让编译器生成这些运算符,而无需编写太多无聊的代码。我刚刚发现boost::unit_steppable据说operator++从前缀一生成后缀,但它只完成了一半的工作:我仍然必须自己提供前缀operator++

以下工作,但在我看来太“强大”:

template <class T> T operator++(T x)
{
    return static_cast<T>(x + 1);
}

我希望只为 selected enums 定义运算符。

4

1 回答 1

2

以下内容应该可以帮助您入门,并根据需要进行扩展:

#include <type_traits>

enum Foo { RED, GREEN, BLUE, SIZE };

template< typename T > struct my_enum_is_unit_steppable { enum { value = false }; };

// for each type you want the operator(s) to be enabled, do this:
template<> struct my_enum_is_unit_steppable< Foo > { enum { value = true }; };

// protect the operators with enable_if
template< typename T >
typename std::enable_if< my_enum_is_unit_steppable< T >::value, T >::type
operator++( T value )
{
    return T( value + 1 );
}

int main()
{
    for( Foo foo = RED; foo != SIZE; ++foo ) {}
}

当然,这使用 C++11 std::enable_if,但 Boost 有可用的 C++03 版本。

于 2013-02-24T12:01:14.813 回答