完美的转发构造函数和继承构造函数

Perfect forwarding constructor and inheriting constructors

鉴于此 class 层次结构:

#include <iostream>

class Base {
public:
    Base() = default;
    Base(const Base&) { std::cout << "  copy\n"; }
    
    template<typename T>
    Base(T&&) { std::cout << "  T&&\n"; }
};

class Sub : public Base {
public:
    using Base::Base;
};

is known 此代码将打印 T&&:

// objects
Base varObj;
const Base constObj;
// invoking constructors
Base copy(varObj);              // T&&
Base move(std::move(constObj)); // T&&
Base number(42);                // T&&

为什么使用 Sub 而不是 Base “解决”了这个问题?

// objects
Sub varObj;
const Sub constObj;
// invoking constructors
Sub copy(varObj);              // copy
Sub move(std::move(constObj)); // copy
Sub number(42);                // T&&

这是CWG2356:继承的构造函数仍然更适合非常量输入(因为需要限定转换),但它被丢弃了通过 [over.match.funcs]/8。这样做的部分原因是为了避免使任何继承构造函数的 class 可从其基础 class.

隐式转换

Sub 复制构造函数(您的两个初始化都使用)仍有可能调用构造函数模板。但是,它的源参数是 const Sub&,所以它的基础子对象是 const Base&。这是 Base 复制构造函数的 精确 匹配,因此它是在模板上选择的(否则由于限定转换或引用种类而获胜)。