当我使用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());
}
我预计编译器会抱怨ExampleClass
没有实现方法bar
。
但是,如果我实际使用方法foo
,它似乎只会抱怨。
我可以在任何兼容C ++ 98和C ++ 11的编译器上依赖此行为吗?
我之前对模板的理解是,无论何时实例化模板,都会复制整个正文,并用模板参数替换T
。这不是模板的工作方式吗?
答案 0 :(得分:11)
根据标准,这是正确的行为。 .load C:\Windows\Microsoft.NET\Framework\v2.0.50727\sos.dll
的定义直到在需要它存在的上下文中使用时才会被实例化。在下面强调我的:
C ++ 03,[temp.inst] / 1:
类模板特化的隐式实例化会导致隐式 声明的实例化,但不是定义或默认参数,类成员函数,成员类,静态数据成员和成员模板;它会导致隐式实例化 成员匿名联盟的定义。除非已经显式实例化或明确专门化了类模板或成员模板的成员,否则该成员的特化是隐式的 在需要成员定义存在的上下文中引用特化时实例化; ...
C ++ 11,[temp.inst] / 1和[temp.inst] / 2:
除非已明确实例化(14.7.2)或明确专门化(14.7.3)类模板特化, 在上下文中引用特化时,将隐式实例化类模板特化 这需要完全定义的对象类型,或者类类型的完整性会影响程序的语义。类模板特化的隐式实例化会导致隐式 声明的实例化,但不是定义或默认参数,类成员函数,成员类,作用域成员枚举,静态数据成员和成员模板; ...除非已明确实例化或明确实例化类模板或成员模板的成员 special,在引用特化时隐式实例化成员的特化 在需要成员定义存在的上下文中; ...