经过一段时间的努力,我看到下面发生了什么,但我仍然不清楚为什么。当我编译代码时,我得到指示的错误消息(仅)。请注意,它上面的一行是完全相同的类型转换,并且工作正常。此外,一旦我命名枚举(结构B),一切正常,如果不涉及模板(test1和test3),一切正常。
这是编译器错误(我正在使用VS 2010)吗?或者有人可以指出规范这部分的那部分吗?
struct A {
enum {
VALUE1
};
enum {
VALUE2
};
};
struct B {
enum Enum1 {
VALUE1
};
enum Enum2 {
VALUE2
};
};
void foo(int x) {
}
template <typename T>
void bar(T x) {
}
void test1() {
foo(A::VALUE1);
foo(A::VALUE2);
}
void test2() {
bar(A::VALUE1);
bar(A::VALUE2); // error C2664: 'bar' : cannot convert parameter 1 from '' to ''
// Conversion to enumeration type requires an explicit cast (static_cast, C-style cast or function-style cast)
}
void test3() {
foo(B::VALUE1);
foo(B::VALUE2);
}
void test4() {
bar(B::VALUE1);
bar(B::VALUE2);
}
答案 0 :(得分:2)
test2
的定义根据2003年标准是不正确的,但在2011年标准中没有问题。但我无法想象为什么编译器会接受一个语句而不接受另一个语句。
C ++ 03 14.3.1 / 2,强调我的:
本地类型,没有链接的类型,未命名类型或从这些类型中复合的类型不得用作 template-argument template type-parameter 。
C ++ 11完全删除了该段落,并将其替换为包含隐式使用未命名的struct
作为模板类型参数的示例。
答案 1 :(得分:1)
我不确定,但对我来说,似乎使用VS中的模板只能使用带名字的类型。由于某些原因,VS编译器无法识别enum只是简单的int,即使它没有名称。这就是为什么test4()
编译没有任何错误而test2()
没有。
修改强>
我挖了一点钱,发现this回答。所以它不是编译器错误。在我看来是一个功能,因为它还检查您的代码是否符合标准。 实际上GCC(vesrion 4.3.4,4.4.5)无论如何都不会编译这段代码
test.cpp: In function 'void test2()':
test.cpp:34: error: no matching function for call to 'bar(A::<anonymous enum>)'
test.cpp:35: error: no matching function for call to 'bar(A::<anonymous enum>)'
但GCC 4.7.3没有错误(使用`-Wall -Wextra --pedantic)它只通知未使用的参数,可能C ++ 0x对模板中未命名的类型不太严格
<强> EDIT2:强>
我在Microsoft Page上发现VS支持Local and unnamed types as template arguments,因此您的代码应该可以运行。所以最后它是一个VS bug!