模板“复制构造函数”不会阻止编译器生成的move构造函数 [英] Template "copy constructor" does not prevent compiler-generated move constructor

查看:138
本文介绍了模板“复制构造函数”不会阻止编译器生成的move构造函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

请考虑以下程序及其中的注释:

Consider the following program and the comments in it:

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时有效地充当复制构造函数)阻止了编译器生成move构造函数,相反,如果我 user define 真正的复制构造函数(通过删除它),那么将不会隐式生成move构造函数(程序将无法编译)? (可能的原因是,当T = U时,模板版本也不尊重复制构造函数的标准定义。)

The question is: why does not user-defining the template constructor (which effectively acts as a copy constructor when U = T) prevent the compiler from generating the move constructor, while, on the contrary, if I user define the "real" copy constructor (by deleting it), then the move constructor is not generated implicitly (the program would not compile)? (Probably the reason is that "template version" does not respect the standard definition of copy-constructor also when T = U?).

好是,这似乎显然是我想要的实际上,我需要 all 复制和移动构造函数 all 编译器将隐式生成的移动和复制赋值运算符,就像S是可以简单地定义为 template< class U> S {}; 以及用于其他 S< U> 的转换的模板构造函数。按照标准,我可以依靠S的上述定义来获得我需要的所有上述内容吗?如果是,则可以避免显式地默认设置它们。

The good thing is that that seems to apparently be what I want. In facts, I need all the copy and move constructors and all the move and copy assignment operators that the compiler would generate implicitly as if S was simply defined as template<class U> S{}; plus the template constructor for the conversions from other S<U>. By standard, can I rely on the above definition of S to have all the mentioned stuff I need? If yes, I could then avoid to "default'ing" them explicitly.

推荐答案

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

The answer is simple - There is no (!) template copy constructor. Even if the template parameter matches the parameter of a copy constructor it is no copy constructor.

请参见12.8复制和移动类对象

See 12.8 Copying and moving class objects


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

A non-template constructor for class X is a copy constructor if its first parameter is of type X&, const X&, volatile X& or const volatile X&, and either there are no other parameters or else all other parameters have default arguments (8.3.6). [ Example: X::X(const X&) and X::X(X&,int=1) are copy constructors.

类似地适用于move构造函数

Similar applies to the move constructor

这篇关于模板“复制构造函数”不会阻止编译器生成的move构造函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆