【问题标题】:c++ why is constructor in this example called twice?c++ 为什么这个例子中的构造函数被调用了两次?
【发布时间】:2011-01-02 21:49:03
【问题描述】:

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

template <typename T1>
struct A{
    template <typename T2>
    A(T2 val){
        cout<<"sizeof(T1): "<<sizeof(T1)<<" sizeof(T2): "<<sizeof(T2)<<endl;
    }
    T1 dummyField;
};

so - 类使用 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调用构造函数两次?

谢谢你满足我的好奇心

【问题讨论】:

    标签: c++ templates constructor


    【解决方案1】:

    如何避免抄袭?

    在这两种情况下都会调用两个构造函数,但是在第一种情况下您看不到它,因为其中一个是编译器生成的。如果要避免复制,则需要使用不同的语法,如下所示:

    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&lt;float&gt;(float val)构造函数构造临时值,然后使用A&lt;bool&gt;( A&lt;float&gt; val)模板化构造函数进行复制。

    【讨论】:

    • 没有构造函数的版本可以创建对象的布尔版本,但将浮点数作为参数?
    • 有,但要使用它,你必须写: A a(3.5f);如果要避免通过另一个构造函数调用进行复制,则需要使用直接初始化语法,而不是赋值语法。
    【解决方案2】:

    在您的第一个示例中,您隐式调用了复制构造函数

    A<bool>(A<bool> const&)
    

    在您的第二个示例中,这不起作用,因为您有两种不同的类型 所以编译器必须使用你的模板构造函数来创建一个新对象 声明

     template <typename T2>
    A(A<T2>const& val){
        cout<<sizeof(val.dummmyField)<<endl;
    }
    

    应该说清楚

    【讨论】:

      【解决方案3】:

      因为您首先创建了模板类的浮动实例。

      这是A&lt;float&gt;(3.5f)-Part。

      然后通过将A&lt;float&gt; 转换为A&lt;bool&gt; 来创建A&lt;bool&gt;。所以首先为A&lt;float&gt;-instance 调用构造函数。调用A&lt;bool&gt; 的复制构造函数。

      【讨论】:

      • 那么对于第二种情况,避免构造函数被调用两次的正确语法是什么?创建 bool 类型的对象,但将 float 类型的参数传递给构造函数?
      • 我已经有一段时间没有使用 c++ 了。我想会的。 A&lt;bool&gt; a(3.5f);
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-12-11
      • 1970-01-01
      • 2015-07-26
      相关资源
      最近更新 更多