g ++未报告未实例化模板中的某些错误

时间:2014-07-24 12:22:30

标签: c++ templates g++

考虑这个例子:

class A
{
  void foo();
  public:
  void bar();
};

template <class> class B
{
  B()
  {
    A a;
    a.foo();    // 1
    A::bar();   // 2
    a.bar(1);   // 3
  }
};

注意B永远不会被实例化。

clang++报告所有三条标记的行都是错误的。 g++(4.8.3)接受行12,仅报告行3

如果B被实例化,g++会愉快地将所有三行报告为错误。

这是g++错误吗?有人会这么认为。 A不是依赖名称,应在模板定义时正常检查其成员。是否有我看不到的细微差别?

2 个答案:

答案 0 :(得分:19)

这些预实例化消息不是由标准强制执行的,而是由编译器决定的

n3337§14.6 - 8

  

对于a的模板定义,不应发出诊断   可以生成有效的专业化。如果没有有效的专业化可以   为模板定义生成,而该模板不生成   实例化后,模板定义格式不正确,无诊断   必需的。

强调我的

答案 1 :(得分:7)

在模板定义时,一般不可能判断a.foo();A::bar();是否为错误,即使是A::foo和{{1}的特定定义也是如此}。

一般来说,A::bar可能有效,如果a.foo();A的某些特殊化作为朋友,而不是其他人,这会使有效性依赖于模板参数。

一般来说,如果B<T>直接或间接地将A::bar();作为基类,B<T>可能有效,并且模板类在模板定义时通常不知道它们的基类

即使可以检测到这些都不可能此处A没有朋友,A没有基础),但它需要重大努力,收效甚微。因此,在实例化时间总是执行此类检查是有意义的,这是GCC采取的方法。

在C ++中实际上没有规则要求在模板定义时诊断它(正如Marco A。的答案正确指出的那样)。只有在实例化模板时,模板定义中的任何错误都会导致程序格式错误,需要诊断,每2.2p1子弹点8:

  

如果任何实例化失败,程序就会格式不正确。

在你的程序中,没有实例化,因此没有实例化失败。