c ++为什么这个例子中的构造函数被调用了两次?

时间:2010-01-08 12:36:14

标签: c++ templates constructor

我只是试着了解以下情况的行为:

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调用两次?

感谢您满足我的好奇心

3 个答案:

答案 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>的复制构造函数。