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

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

4

2 回答 2

9

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

GCC 不接受它。并不是说这必然意味着它是不正确的,但是无论如何,你都有一个例子来说明应该发生的事情。

于 2012-07-21T05:36:20.103 回答
7

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

然而,实现可以指向标准的规范部分,这些部分允许它们比“显而易见的”规则似乎陈述的更进一步。我将在下面描述这一点。

非规范性描述

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

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

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

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


规范性描述

这些规则具有“不需要诊断”的质量。值得注意的是,即使模板被实例化,这些规则的实现也被授予不诊断格式错误的模板定义的许可,尽管标准的非规范性说明是这样说的。如果违反了不需要诊断的任何规则,则实现可以自由地对整个程序做任何它想做的事情。

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

Last but not least, the committee knows about these "loopholes", but there was no majority to change this so far, as far as I know.

于 2012-07-21T11:08:50.597 回答