4

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

2 回答 2

2

的定义test2根据 2003 年标准格式不正确,但在 2011 年标准中可以。但我无法想象为什么编译器会接受一个语句而不接受另一个语句。

C++03 14.3.1/2,强调我的:

本地类型、没有链接的类型、未命名类型或由这些类型中的任何一种组合而成的类型不得用作模板类型参数模板参数。

C++11 完全删除了该段落,并将其替换为一个示例,该示例包含隐式使用未命名struct作为模板类型参数。

于 2013-06-09T21:03:24.450 回答
1

我不确定,但对我来说,使用 VS 中的模板似乎只能使用带名称的类型。出于某种原因,即使没有名称,VS 编译器也无法识别 enum 只是简单的 int 。这就是为什么test4()编译没有任何错误而test2()不是。

编辑:

我深入挖掘并找到了这个答案。所以这不是编译器错误。在我看来,这是一项功能,因为它还会检查您的代码是否符合标准。事实上 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 对模板中的未命名类型不太严格

编辑2:

我在Microsoft Page上发现 VS 支持本地和未命名类型作为模板参数,因此您的代码应该可以工作。所以最后它是一个VS错误!

于 2013-06-09T20:40:04.340 回答