我正在尝试使我的程序中的作用域枚举可比较底层类型,但以下代码不起作用。这是因为我使用的编译器(VC11)对C++11标准支持不好,还是因为代码违反了C++11标准的某些规则?如果是后者,具体违反了哪些规则(欢迎引用特定标准条款)?
#include <type_traits>
enum class Test: short int { A,B,C };
template<typename E> bool operator != (E e, typename std::underlying_type<E>::type n)
{
return static_cast<typename std::underlying_type<E>::type>(e) != n;
}
template<typename E> bool operator != (typename std::underlying_type<E>::type n, E e)
{
return static_cast<typename std::underlying_type<E>::type>(e) != n;
}
int main()
{
short int x = 123;
x != Test::B; // compilation error
}
这是为什么我认为我的代码应符合C++11标准。引用C++11标准的一段话(14.8.3.1):
对于每个函数模板,如果参数推导和检查成功,则使用模板参数(推导的和/或显式的)来综合声明单个函数模板专业化,该专业化添加到候选函数集以用于重载解析。 如果给定函数模板的参数推导失败,则不会将此类函数添加到该模板的候选函数集中。
编辑。 我的代码不符合C++11标准(感谢Vaughn Cato和Andy Prowl的解释)。 Andy Prowl的答案提供了替代的可行代码。
附注。最终,我使用命名空间使非作用域枚举变得有作用域:
namespace Test_ {
enum Test { A,B,C };
};
using Test_::Test;
namespace Test2_ {
enum Test2 { Z,Y,B };
};
using Test2_::Test2;
std::underlying_type<E>::type
的情况。这不是在评论中简单解释的,但你可以阅读这个问答来理解它。 - Andy Prowl