模板类方法不会导致错误 - 这是标准的一部分吗?

mat*_*ots 6 c++ templates c++11

当我编译以下内容时g++ --std=c++98 -Wall -Werror -Wpedantic Test.cc,没有错误.

template <class T>
struct TemplateClass {
  T *ptr;

  TemplateClass(T *p): ptr(p) {}

  int foo() {
    return ptr->bar();
  }
};

struct ExampleClass {
};

int main() {
  TemplateClass<ExampleClass> x(new ExampleClass());
}
Run Code Online (Sandbox Code Playgroud)

我预计编译器会抱怨ExampleClass没有实现方法bar.

但看起来它只是抱怨我实际使用的方法foo.

我可以在任何符合C++ 98和C++ 11的编译器上依赖此行为吗?

我之前对模板的理解是,无论何时实例化模板,都会复制整个主体并T替换为模板参数.这不是模板的工作原理吗?

Bri*_*ian 11

根据标准,这是正确的行为.foo除非在需要存在的上下文中使用,否则不会实例化该定义.强调我的以下内容:

C++ 03,[temp.inst]/1:

类模板特化的隐式实例化会导致类成员函数,成员类,静态数据成员和成员模板的声明的隐式实例化,而不是定义或默认参数的隐式实例化.它会导致成员匿名联合的定义的隐式实例化.除非已显式实例化或明确专门化类模板或成员模板的成员,否则在需要成员定义存在的上下文中引用特化时,将隐式实例化成员的特化; ...

C++ 11,[temp.inst]/1和[temp.inst]/2:

除非已经显式实例化了类模板特化(14.7.2)或显式专用(14.7.3),否则在需要完全定义的对象类型或完整性的上下文中引用特化时,将隐式实例化类模板特化.类类型会影响程序的语义.类模板特化的隐式实例化导致类成员函数,成员类,作用域成员枚举,静态数据成员和成员模板的声明的隐式实例化,而不是定义或默认参数的隐式实例化....除非已经显式实例化或明确专门化了类模板或成员模板的成员,否则在需要成员定义存在的上下文中引用特化时,将隐式实例化成员的特化; ...