用户定义的构造函数重载未与参数超类的重载进行参数匹配

User-defined constructor overload not being parameter-matched to the overload with the argument's superclass

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

#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. 在 (1) 处,我们生成一个 Boo<int> 实例 x,它使用 Boo<T>::Boo() 构造函数重载。
  2. 在 (2) 处,我们将实例 x 传递给实例 y 的构造函数,它使用隐式定义的复制构造函数 Boo<T>::Boo(Boo<T> const &)。因此,我们没有收到输出消息。
  3. 在 (3) 处,我们将实例 x 传递给实例 z 的构造函数,它使用 Boo<T>::Boo(Foo const &) 构造函数重载。
  4. 在(4)处,我们确认Boo<int>可以被编译器隐式转换为Foo const &并传递给fun(Foo const &)函数。

问题:我怎样才能让 (2) 通过与 (3) 相同的构造函数,为什么它还没有这样做?

如果有人能看到我遗漏的内容,请向我指出,我将不胜感激。

使用委托构造函数:

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&) 并手动调用它更匹配。