在比较两个不同的枚举时,有没有正确的方法来避免警告?

时间:2009-01-28 05:23:27

标签: c++ templates gcc enums

当比较来自不同来源的枚举时,例如以下代码的枚举,GCC会发出警告。有没有办法在没有c风格演员表的情况下避免这些警告?

struct Enumerator
{
    enum { VALUE = 5 };
};

template<int V>
struct TemplatedEnumerator
{
    enum { VALUE = V };
};

if(Enumerator::VALUE == TemplatedEnumerator<5>::VALUE)
{
  ...
}

GCC会发出以下类型的警告:

GCC: warning: comparison between 'enum ...' and 'enum ...'

6 个答案:

答案 0 :(得分:8)

我相信你可以提供自己的比较运算符,但你必须首先命名枚举:

struct Enumerator
{
    enum Values { VALUE = 5 };
};

template<int V>
struct TemplatedEnumerator
{
    enum Values { VALUE = V };
};


template <int V>
bool operator==(Enumerator::Values lhs, typename TemplatedEnumerator<V>::Values rhs)
{
    return static_cast<int>(lhs) == static_cast<int>(rhs);
}

template <int V>
bool operator==(typename TemplatedEnumerator<V>::Values rhs, Enumerator::Values lhs)
{
    return static_cast<int>(lhs) == static_cast<int>(rhs);
}

有趣的是,Visual Studio实际上没有警告比较两个枚举器类型,而是警告if语句中的常量值 - 就像你执行此操作一样:

if (true) {...}

答案 1 :(得分:2)

如果有N个枚举,是否需要N *(N-1)个比较运算符?这可能最终会成为很多。

难道你不能只使用enums隐式转换为int并执行:

bool equals(int lhs, int rhs)
{
  return lhs == rhs;
}

然后你可以在代码中执行此操作:

if(equals(Enumerator::VALUE, TemplatedEnumerator<5>::VALUE))
{
  ...
}

另外,您可以查看enum-int casting: operator or function。接受的答案是你不应该使用隐式转换,但正确命名的函数(如equals)应该使代码具有可读性和可维护性。

答案 2 :(得分:2)

不要这样做。

警告就在那里,因为你不应该首先混淆不同的枚举。

对于常量,您可以使用const声明。

答案 3 :(得分:1)

#include <iostream>
using namespace std;

struct Enumerator 
{
  enum {value = 5 };
};


template<int v>
struct TemplatedEnumerator
{ 
  enum {value = v};
};



int main(void)
{
  if (static_cast<int>(Enumerator::value) ==
    static_cast<int>(TemplatedEnumerator<5>::value))
    cout << "Yoh\n";
}

答案 4 :(得分:1)

你错过了明显的答案。不,不要使用c式演员。使用C ++风格的强制转换:

if(static_cast<int>(Enumerator::VALUE) == static_cast<int>(TemplatedEnumerator<5>::VALUE))
{

}

完全安全,完全可以接受。两个枚举不是相同的类型,所以如果你的代码中有任何可疑的东西,它不是演员,那就是尝试比较两种不同的类型。但只要你这样做,演员就是我的首选方式。是的,您可以定义一个比较运算符,但是演员表明您正在比较两个技术上不相关的类型。

答案 5 :(得分:1)

在您的情况下简单回答:不要使用enum,使用内联定义的static const int

struct Enumerator
{
    static int const VALUE = 5;
};

template<int V>
struct TemplatedEnumerator
{
    static int const VALUE = V;
};

在这个特殊情况下,这是等效的,过去几年的所有编译器都应该这样对待(我知道所有主要的编译器都这样做。)

另请参阅:static const Member Value vs. Member enum : Which Method is Better & Why?