为什么此代码不生成编译错误?

Why doesn't this code generate compilation errors?

本文关键字:编译 错误 代码 为什么      更新时间:2023-10-16
template<class T>
void foo()
{
    M
}

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

因为视觉C++错误。 它不实现两阶段查找。 即使您不实例化模板,它也应该检查模板的语法是否正确,但它不会这样做。

海湾合作委员会不接受它。不说这必然意味着它不对,但无论如何,有一个应该发生的事情的例子。

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

但是,实施可以指向标准的规范部分,这些部分允许它们比"明显"规则似乎声明的内容更进一步。我将在下面描述这一点。

非规范性描述

该标准允许实现在实例化模板定义之前不检查模板定义。它没有给出关于"模板定义"何时实际上应该是模板定义的正式描述,但通常的实现是执行"大括号平衡"/"括号平衡"的形式:从定义正文的最外大括号开始,计数直到你点击最后一个右大括号。介于两者之间的所有内容都将被忽略。

我想标准的一个例子进一步澄清了这一点

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

因此,早期诊断模板定义中的语法或语义错误是一种"实现质量"。


规范性描述

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

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

最后但并非最不重要的一点是,委员会知道这些"漏洞",但据我所知,到目前为止还没有大多数人改变这一点。