【问题标题】:How to define increment/decrement/etc operator automatically?如何自动定义递增/递减/等运算符?
【发布时间】:2013-02-24 11:30:30
【问题描述】:

我有一堆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;
}

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

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);
}

我希望仅为选定的enums 定义运算符。

【问题讨论】:

  • 我认为这不是一个好主意。
  • 你绝对绑定到 C++03 吗?
  • @Xeo 是的(必须用 MS Visual Studio 2005 编译)。
  • 这样的模板会给你带来很多麻烦,不仅仅是enum Color {red = 1, blue = 42};
  • @Cicada 你认为什么是坏主意:使用模板生成这样的代码,或者重载任何运算符? (如果您解释原因,您也可以将其格式化为答案)

标签: c++ templates enums operator-overloading c++03


【解决方案1】:

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

#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 版本。

【讨论】:

  • 请注意,等效的 Boost 版本是 boost::enable_if&lt;trait&lt;T&gt;, T&gt;boost::enable_if_c&lt;trait&lt;T&gt;::value, T&gt;
猜你喜欢
  • 2011-02-16
  • 1970-01-01
  • 1970-01-01
  • 2015-10-03
  • 2014-03-21
  • 2015-02-16
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多