模板中的枚举促销。为什么它有时会起作用而不起作用?

时间:2013-06-09 19:51:11

标签: c++

经过一段时间的努力,我看到下面发生了什么,但我仍然不清楚为什么。当我编译代码时,我得到指示的错误消息(仅)。请注意,它上面的一行是完全相同的类型转换,并且工作正常。此外,一旦我命名枚举(结构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);
}

2 个答案:

答案 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!