不存在的标识符,用作非实例化函数模板中的默认参数

时间:2014-02-05 15:56:55

标签: c++ templates visual-c++ c++11 language-lawyer

今天我找到了一段相当于以下内容的代码:

enum X
{
    x1 = 0,
    x2 = 1
};

template<typename T>
void bar(T obj, X x = x3) { }
//                    ^^
//                    This identifier is bogus!

int main() { }

VC10和VC12都很乐意编译它。 clang 3.4和GCC 4.8.1都拒绝它(这是我所期望的)。

这是一个错误,还是标准实际允许VC的行为?如果是,哪些是相关段落?

1 个答案:

答案 0 :(得分:11)

众所周知,VC没有两阶段查找。这意味着它接受模板中的各种bogosity,只要它至少看起来像语法上有效的C ++并且它实际上没有被实例化。

这只是其中一个例子。

正如您在conformance roadmap中看到的那样,计划在RTM后CTP之后的某个时间进行两阶段查找,我想这意味着在您支付下一次迭代后,您将可以访问它。 Visual Studio套件。

至于标准参考,14.6 / 9-10说:

  

在查找模板定义中使用的名称声明时,通常的查找规则(3.4.1,3.4.2)用于非依赖名称。 [...]

     

如果名称不依赖于模板参数(如14.6.2中所定义),则该名称的声明(或声明集)应在名称出现在模板定义中的范围内。