按照下面的代码片段,我尝试通过Boo<int>构造函数重载传递Boo<T>::Boo(Foo const &)实例,但我无法做到这一点。

#include <iostream>

struct Foo { };

template <typename T>
struct Boo : public Foo
{
    // Boo(Boo<T> const &) = delete; // Leaves (2) without a constructor

    Boo()            { std::cout << "Beep " << sizeof(T) << std::endl; }
    Boo(Foo const &) { std::cout << "Boop " << sizeof(T) << std::endl; }
};

void fun(Foo const &) { }

int main()
{
    Boo<int> x;       // (1) Output: Beep 4
    Boo<int> y(x);    // (2) Output:
    Boo<double> z(x); // (3) Output: Boop 8
    fun(x);           // (4) Compiles

    return 0;
}

在代码段中,我尝试编写一种简单的方案,如果需要,可以将其复制粘贴以进行操作。
  • 在(1),我们生成一个Boo<int>实例x,它使用Boo<T>::Boo()构造函数重载。
  • 在(2),我们将实例x传递给实例y的构造函数,该实例使用隐式定义的副本构造函数Boo<T>::Boo(Boo<T> const &)。因此,我们不会收到输出消息。
  • 在(3)处,我们将实例x传递给实例z的构造函数,该实例使用Boo<T>::Boo(Foo const &)构造函数重载。
  • 在(4),我们确认Boo<int>可以由编译器隐式转换为Foo const &,并传递给fun(Foo const &)函数。

  • 问题:如何获得(2)与(3)相同的构造函数,为什么它还没有这样做?

    如果有人看到我错过了什么,我会很感激,如果它指出了我。

    最佳答案

    使用委托(delegate)的构造函数:

    template <typename T>
    struct Boo : public Foo
    {
        Boo(Boo<T> const & arg) : Boo(static_cast<Foo const&>(arg)) {};
    
        Boo()            { std::cout << "Beep " << sizeof(T) << std::endl; }
        Boo(Foo const &) { std::cout << "Boop " << sizeof(T) << std::endl; }
    };
    

    解决此问题的原因在于,不再存在隐式副本构造函数,这比将其转换为Foo const&并使用构造函数Boo<T>::Boo(Foo const&)更好,并且可以手动调用它。

    关于c++ - 用户定义的构造函数重载与参数的父类(super class)的重载参数不匹配,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/57437673/

    10-09 13:36