完美的转发构造函数和继承构造函数
鉴于此类层次结构:
#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;
};
这是已知的,该代码将打印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 丢弃。部分原因是为了避免使继承构造函数的任何类从其基类隐式转换。
还有的可能性Sub拷贝构造函数(双方你的初始化的使用)将调用构造函数模板。但是,它的源参数是 a const Sub&,所以它的基础子对象是 a const Base&。这是复制构造函数的完全匹配Base,因此它是通过模板选择的(否则会因为限定转换或引用类型而获胜)。