【发布时间】:2014-07-18 19:10:55
【问题描述】:
考虑以下程序和其中的 cmets:
template<class T>
struct S_ {
S_() = default;
// The template version does not forbid the compiler
// to generate the move constructor implicitly
template<class U> S_(const S_<U>&) = delete;
// If I make the "real" copy constructor
// user-defined (by deleting it), then the move
// constructor is NOT implicitly generated
// S_(const S_&) = delete;
};
using S = S_<int>;
int main() {
S s;
S x{static_cast<S&&>(s)};
}
问题是:为什么用户定义模板构造函数(当 U = T 时有效地充当复制构造函数)阻止编译器生成移动构造函数,而相反,如果我用户定义“真正的”复制构造函数(通过删除它),那么移动构造函数不会隐式生成(程序不会编译)? (可能原因是“模板版本”在 T = U 时也不尊重复制构造函数的标准定义?)。
好消息是这显然是我想要的。事实上,我需要 all 复制和移动构造函数 和 all 编译器会隐式生成的移动和复制赋值运算符,就好像 S 是简单地定义为template<class U> S{}; 加上模板构造函数,用于从其他S<U> 进行转换。按照标准,我可以依靠上面对 S 的定义来拥有我需要的所有提到的东西吗?如果是,我可以避免明确地“默认”它们。
【问题讨论】: