我只是试着了解以下情况的行为:
template <typename T1>
struct A{
template <typename T2>
A(T2 val){
cout<<"sizeof(T1): "<<sizeof(T1)<<" sizeof(T2): "<<sizeof(T2)<<endl;
}
T1 dummyField;
};
所以 - 该类用T1模板化,构造函数用T2模板化
现在 - 如果我写:
A<bool> a = A<bool>(true);
输出符合预期:
sizeof(T1): 1 sizeof(T2): 1
然而 - 如果我写:
A<bool> a = A<float>(3.5f);
输出是:
sizeof(T1): 4 sizeof(T2): 4
sizeof(T1): 1 sizeof(T2): 4
为什么构造函数使用模板参数float调用两次?
感谢您满足我的好奇心
答案 0 :(得分:7)
在这两种情况下都调用了两个构造函数,但是在第一种情况下你没有看到它,因为其中一个是编译器生成的构造函数。如果要避免复制,则需要使用不同的语法,如下所示:
A<bool> a(true);
A<bool> a(3.5f);
A<bool> a = A<bool>(true);
这里A(bool val)构造函数用于构造临时值,而默认编译器生成的复制构造函数用于执行A到A的复制。您正在复制相同类型,并且对于相同类型的复制构造函数是用过的。这里有趣且不明显的事实是:模板构造函数永远不会用作复制构造函数,即使它看起来像一个。
A<bool> a = A<float>(3.5f);
首先使用A<float>(float val)
构造函数构造临时值,然后使用A<bool>( A<float> val)
模板化构造函数来执行复制。
答案 1 :(得分:6)
A<bool>(A<bool> const&)
在你的第二个例子中,由于你有两种不同的类型,因此无法工作 所以编译器必须使用模板化构造函数来创建一个新对象 声明
template <typename T2>
A(A<T2>const& val){
cout<<sizeof(val.dummmyField)<<endl;
}
应该明确这个
答案 2 :(得分:3)
因为您首先创建模板类的float-instance。
这是A<float>(3.5f)
- Part。
然后通过将A<bool>
隐藏到A<float>
来创建A<bool>
。因此首先为A<float>
- 实例调用构造函数。调用A<bool>
的复制构造函数。