为什么这段代码不会产生编译错误?

时间:2012-07-21 05:32:54

标签: c++ templates visual-c++

template<class T>
void foo()
{
    M
}

除非我实例化它,否则Visual C ++不会告诉我上面的代码包含错误。这是为什么?

2 个答案:

答案 0 :(得分:9)

因为Visual C ++出错了。它没有实现two-phase lookup。它应该检查模板的正确语法,即使你没有实例化它,但它不会这样做。

GCC doesn't accept it.不是说这必然意味着它是不对的,但无论如何都有一个例子可以解释你应该发生的事情。

答案 1 :(得分:7)

C ++标准包含对此问题的非正式描述,描述了我认为是一个很好的指导方针,并被许多人视为规范所暗示的规范性要求。

然而,实现可以指向标准的规范部分,使它们比“明显的”规则似乎更加明确。我将在下面描述。

非规范性描述

标准允许实现在实例化之前不检查模板定义。它没有给出关于何时“模板定义”实际上应该是模板定义的正式描述,但通常的实现是做“支撑平衡”/“平衡”的形式:从最外面的支撑开始定义的主体,直到你击中最后一个结束括号。中间的一切都被忽略了。

我认为标准中的一个例子进一步说明了这一点

template<class T> class X {
  // ... (omitted) ...
  void g(T t) {
    +; // may be diagnosed even if X::g is not instantiated
  }
};

因此,模板定义中语法或语义错误的早期诊断是“实施质量”。


规范性描述

这些规则的质量“无需诊断”。值得注意的是,尽管标准的非规范性说明如此,但这些规则的实现被授予不诊断格式错误的模板定义的许可,即使模板已实例化。如果违反了任何不需要诊断的规则,则实现可以随意对整个程序执行任何操作。

应该注意的是,也没有语法错误的“模板定义”,因为这个术语是由语法本身定义的。孤独的+使整个封闭的上下文成为一些无意义的令牌。

最后但并非最不重要的是,委员会知道这些“漏洞”,但据我所知,迄今为止没有多数改变这一点。