template<class T>
void foo()
{
M
}
除非我实例化它,否则Visual C ++不会告诉我上面的代码包含错误。这是为什么?
答案 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
}
};
因此,模板定义中语法或语义错误的早期诊断是“实施质量”。
这些规则的质量“无需诊断”。值得注意的是,尽管标准的非规范性说明如此,但这些规则的实现被授予不诊断格式错误的模板定义的许可,即使模板已实例化。如果违反了任何不需要诊断的规则,则实现可以随意对整个程序执行任何操作。
应该注意的是,也没有语法错误的“模板定义”,因为这个术语是由语法本身定义的。孤独的+
使整个封闭的上下文成为一些无意义的令牌。
最后但并非最不重要的是,委员会知道这些“漏洞”,但据我所知,迄今为止没有多数改变这一点。