这是 C++ 入门第 5 版中的一个练习:
“练习 16.26:假设NoDefault
是一个没有默认构造函数的类,我们可以显式实例化vector<NoDefault>
吗?如果没有,为什么不呢?”
这是我的猜测:
是的,我们可以实例化它:
template <typename T>
class Foo
{
public:
void func(){cout << x_.value_ << endl;}
private:
T x_;
};
class Bar
{
public:
Bar(int x) : value_(x){}
void print(){}
private:
int value_{};
template <class T>
friend class Foo;
};
extern template class Foo<Bar>; // instantiation declaration
template class Foo<Bar>; // instantiation definition
int main()
{
// Foo<Bar> f;
}
代码工作正常,但如果我取消注释 main 中的行,我会得到预期的错误,因为Bar
它不是默认可构造的。
如果我使用与Bar
元素类型相同的类,std::vector
则它不起作用:
extern template class vector<Bar>; // declaration ok
template class vector<Bar>; // instantiation: doesn't work?!
那么为什么我的
Foo<Bar>
实例化有效但无效vector<Bar>
呢?在我看来,
vector<Bar>
不工作是合乎逻辑的,因为显式的实例化定义实例化了类模板的所有成员(甚至是未使用的成员);在这个例子中,其中的默认构造函数Foo<Bar>
意味着ctor
其元素类型的默认值Bar
;后者不提供;毕竟Foo<Bar>()
通常被声明为已删除的成员函数,因为x_
没有默认构造函数。所以我不知道为什么Foo<Bar>
定义有效?!谢谢你。