我刚刚阅读了关于CRTP的wiki文章,我对模板实例化感到有些困惑。
根据维基,
成员函数体(定义)直到很久才会实例化 在他们的声明之后。
我不太明白这意味着什么。
假设我有一个类模板:
template <typename T>
class A
{
public:
void foo(T t)
{
//...
};
};
当我实例化类模板A时,是否实例化成员函数foo()?
例如:
//in .cpp file
int main()
{
A<int> a; //question 1
//class template is instantiated here, isn't it?
//What about foo(), is it instantiated too?
a.foo(10); //question 2
//according to the quotation, foo() will not be instantiated until it is used.
//if so, foo() is instantiated right here, not in question 1, right?
}
答案 0 :(得分:12)
你似乎有点困惑:
实例化在编译期间发生,而不是在运行时期间。因此,您不能说“在哪一行”实例化类模板或函数模板。
也就是说,你对成员函数模板没有与类模板一起实例化是正确的。
你可以在这种情况下观察它:你有以下文件
然后在编译a.cpp期间,只会实例化A。但是,在编译b.cpp期间,两者都将被实例化。
因此,如果A :: foo包含一组给定模板参数的语义无效代码,则会在b.cpp中出现编译错误,但不会出现a.cpp。
我希望能够解决问题!
答案 1 :(得分:9)
使用类模板,经验法则是只实例化那些实际使用的成员。
如果你想要完整的实例化,C ++提供显式实例化(但是,通常你不会;事实上并非每一位都被完全实例化,这意味着你的模板类更加通用,因为它降低了对T
的要求,请注意语法检查和查找非依赖类型(不依赖于T
的东西)仍然会发生。)
您可以在此处找到更完整的答案:Template instantiation details of GCC and MS compilers