【发布时间】:2014-02-06 09:24:52
【问题描述】:
这是C++ Primer 5th Edition中的一个练习:
练习 16.27:对于每个带标签的陈述,解释什么,如果有的话, 实例化发生。如果模板被实例化,请解释原因;如果 不,解释为什么不。第677页
template <typename T> class Stack { };
void f1(Stack<char>); // (a)
class Exercise {
Stack<double> &rsd; // (b)
Stack<int> si; // (c)
};
int main() {
Stack<char> *sc; // (d)
f1(*sc); // (e)
int iObj = sizeof(Stack< string >); // (f)
}
以下是我尝试过的:
(a) Stack<char> 被实例化,但没有任何成员被实例化。
(b) Stack<double> 被实例化,但没有任何成员被实例化。
(c) Stack<int> 及其默认构造函数被实例化。
(d) (e) 完全不知道...
(f) Stack< string > 被实例化,但没有任何成员被实例化。
我说的对吗?谁能告诉我这段代码是如何实例化的?
【问题讨论】:
-
如果有疑问,您可以添加相关的静态断言(或类似的东西来强制编译时错误),例如断言
T是void。然后,成员函数中的失败断言会告诉您该成员函数已实例化。当你知道会发生什么时,解释它发生的原因就变得容易多了。成员函数外部的失败断言同样会告诉您该类本身已实例化。 -
@hvd 谢谢。因为我以前从未使用过断言。我试图理解这种方法。在这种情况下,由于所有的复制和控制成员都是合成版本,我应该像默认构造函数那样编写自定义版本并将断言放入其中吗?如果它没有编译,这意味着这个默认构造函数被实例化了。我说的对吗?
-
是的,我就是这个意思。您首先检查(使用 David Kernin 的回答)在哪些情况下类本身会被实例化。然后,您可以将类(从答案复制断言样式)更改为,例如,
template <typename T> class Stack { public: Stack() { typedef typename T::ThisDoesntExist StaticAssert; } };以检测默认构造函数的使用位置。
标签: c++ templates instantiation