【问题标题】:Template "copy constructor" does not prevent compiler-generated move constructor模板“复制构造函数”不会阻止编译器生成的移动构造函数
【发布时间】: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&lt;class U&gt; S{}; 加上模板构造函数,用于从其他S&lt;U&gt; 进行转换。按照标准,我可以依靠上面对 S 的定义来拥有我需要的所有提到的东西吗?如果是,我可以避免明确地“默认”它们。

【问题讨论】:

    标签: c++ c++11


    【解决方案1】:

    答案很简单 - 没有 (!) 模板复制构造函数。即使模板参数与复制构造函数的参数匹配,它也不是复制构造函数。

    参见 12.8 复制和移动类对象

    类 X 的非模板构造函数是一个复制构造函数,如果它 第一个参数的类型为 X&、const X&、volatile X& 或 const volatile X&,或者没有其他参数,或者其他所有参数 参数具有默认参数 (8.3.6)。 [ 示例:X::X(const X&) 和 X::X(X&,int=1) 是复制构造函数。

    同样适用于移动构造函数

    【讨论】:

      【解决方案2】:

      没有模板复制构造函数这样的东西。仍然会生成常规(非模板化)复制构造函数,并且比模板化的构造函数与您提供的签名更好地匹配(由于混合中抛出的“通用”引用,事情变得更加复杂,但这是题外话)。

      【讨论】:

        【解决方案3】:

        复制构造函数和移动构造函数不是模板化的。 C++ 标准具体说明了复制构造函数的构成。

        发件人:http://en.cppreference.com/w/cpp/language/copy_constructor

        类T的拷贝构造函数是一个非模板构造函数,它的第一个参数是T&,const T&,volatile T&,或者const volatile T&,或者没有其他参数,或者其余参数都有默认值.

        【讨论】:

        • 实际上,这不是标准的引用。 标准的意思,但标准实际上读作“类 X 的非模板构造函数是复制构造函数 if [...]”。该标准的措辞可以解释为未指定模板构造函数是否也可以是复制构造函数,因此您链接到的页面上的措辞更好,但我不同意您答案的“C++ 标准非常具体”部分. :)
        • @hvd,正确,这是引用的引用。不过,对措辞的有趣观察。
        猜你喜欢
        • 2017-07-20
        • 1970-01-01
        • 2019-04-16
        • 1970-01-01
        • 2015-06-30
        • 2022-01-12
        • 2016-09-12
        • 1970-01-01
        • 2012-10-21
        相关资源
        最近更新 更多