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

Non-existing identifier used as default argument in non-instantiated function template

今天发现一段代码相当于如下:

1
2
3
4
5
6
7
8
9
10
11
12
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 的行为?如果有,哪些是相关段落?


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

这只是其中一个例子。

正如您在他们的一致性路线图中所看到的,两阶段查找计划在 RTM CTP 之后的某个时间进行,我猜这意味着您将在为 Visual Studio 套件的下一次迭代付费后访问它.

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

When looking for the declaration of a name used in a template definition, the usual lookup rules (3.4.1, 3.4.2) are used for non-dependent names. [...]

If a name does not depend on a template-parameter (as defined in 14.6.2), a declaration (or set of declarations) for that name shall be in scope at the point where the name appears in the template definition.