【问题标题】:Calling the right constructor调用正确的构造函数
【发布时间】:2014-04-08 21:25:20
【问题描述】:

我有一个带有两个构造函数的类 X,定义如下:

template <typename T>
class X {
  template <typename U>      
  X(U& u) {
   // some logic
  }

  X(const Y<T>& y) {
    // some other logic
  }
};

类 Y 有一个返回 Y 类型对象的静态方法。

template <typename T>
class Y {
  static Y<T> myStaticMethod(const T& t) {
    // some logic
  }
};

现在如果我尝试,下面的代码:

const Y<double>& obj = Y<double>::myStaticMethod(1.0);
X<double> xObj = new X<double>(obj);

具有双重模板 T 和 U 的构造函数被调用, T = double 这是预期的,但 U = Y&lt;double&gt;* 这是相当意外的。

我希望调用 X 的第二个构造函数,但它没有发生。还有,为什么我用引用调用构造函数时,obj会被转换成指针?

【问题讨论】:

  • 您的构造函数模板太贪心,它说“允许从任何左值进行任何转换”,然后可能无法实际执行此转换。 new 在 C++ 中不需要定义对象(据我所知,这里是错误的)。

标签: c++ templates constructor


【解决方案1】:

考虑你的路线:

X<double> xObj = new X<double>(obj);

这告诉编译器获取新表达式的结果,并且 将它们转换为X&lt;double&gt;。新结果的类型 表达式为X&lt;double&gt;*X&lt;double&gt; 的唯一构造函数 可以用指针调用的是template &lt;typename T&gt; X:X(U&amp; )。 除了它也不能被调用,因为它需要绑定一个 右值到非常量引用。但是有些编译器坏了,而且 还是允许吧。

按照写的,代码不应该编译,但如果编译,它应该调用X&lt;double&gt;的构造函数两次。

【讨论】:

    【解决方案2】:

    把那条线拆开,分成两行。

    X<double>* xObjPtr = new X<double>(obj);
    X<double> xObj = xObjPtr;
    

    现在编译器尝试调用的原因是否有意义:

    template <typename U> X(U& u) {}
    

    U == X&lt;double&gt;*

    【讨论】:

    • 但他说的是U == Y*。也许是他的错字,他的意思是X&lt;double&gt;*
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-07-27
    • 1970-01-01
    • 2021-11-12
    • 2011-05-18
    • 2014-10-25
    • 2021-06-04
    • 2021-09-27
    相关资源
    最近更新 更多