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おそらくプレフィックス1からポストフィックスを生成することがわかりましたoperator++が、それは半分の作業しか実行しません。それでもプレフィックスをoperator++自分で提供する必要があります。

以下は機能しますが、私の意見では「強力」すぎます。

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

選択したに対してのみ演算子を定義してもらいたいenumのですが。

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 に答える