Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/147.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 警告:删除多个副本构造函数时定义了它们_C++_C++11 - Fatal编程技术网

C++ 警告:删除多个副本构造函数时定义了它们

C++ 警告:删除多个副本构造函数时定义了它们,c++,c++11,C++,C++11,环境:VS2015更新3,64位(调试版)编译 在下面的代码中,如果我取消注释Maybe(X&)=delete行,我会得到下面代码和问题标题中提到的警告 现在,我知道,在C++(11?)中有一些规则,它们可能会 显式删除该构造函数已过时。只是,即使在搜索之后 有一段时间,我在网上找不到一条明确的规则,可以证实这一点 如果我只删除Maybe(const X&)=delete,编译器将不会自动生成另一个副本构造函数 因此,我的问题首先是: 谁能指出我在C++规范中的位置,它清楚地定义了 自动生成复制

环境:VS2015更新3,64位(调试版)编译

在下面的代码中,如果我取消注释
Maybe(X&)=delete
行,我会得到下面代码和问题标题中提到的警告

现在,我知道,在C++(11?)中有一些规则,它们可能会 显式删除该构造函数已过时。只是,即使在搜索之后 有一段时间,我在网上找不到一条明确的规则,可以证实这一点 如果我只删除
Maybe(const X&)=delete
,编译器将不会自动生成另一个副本构造函数

因此,我的问题首先是: 谁能指出我在C++规范中的位置,它清楚地定义了 自动生成复制构造函数的规则?或者,一些不太正式的 关于如何确定会发生什么的简单易记的经验法则也会受到欢迎

template <class X>
class Maybe
{
    X *m_just;
public:
    explicit Maybe(const X& x)
        : m_just(new X(x))
    {}
    Maybe()
        : m_just(nullptr)
    {}
    Maybe(const Maybe<X>&& other)
        : m_just(other.m_just)
    {
        other.m_just = nullptr;
    }
    Maybe(const Maybe<X>&) = delete;
    // If line below is uncommented, this produces the warning: 
    // warning C4521: 'Maybe<Int32>': multiple copy constructors specified
    // Maybe(Maybe<X>&) = delete; 

    ~Maybe()
    {
        delete m_just;
        m_just = nullptr;
    }
    // ... more members and code which are not related to question
    // ...
};
模板
也许是上课吧
{
X*m_刚刚;
公众:
显式可能(常数X&X)
:m_just(新X(X))
{}
也许
:m_just(nullptr)
{}
可能(const-Maybe&&other)
:m_just(其他.m_just)
{
other.m_just=nullptr;
}
Maybe(const Maybe&)=删除;
//如果下面的行未注释,则会产生警告:
//警告C4521:“可能”:指定了多个副本构造函数
//Maybe(Maybe&)=删除;
~Maybe()
{
删除m_just;
m_just=nullptr;
}
//…更多与问题无关的成员和代码
// ...
};

请不要对那门课的整个想法发表评论。这只是我私人实验室里的私人修补……;)

>我的C++有点生锈,所以这可能是错误的,但是我认为你不应该甚至有一个非const拷贝构造函数(除了移动构造函数自然地)。p> 如果
a=b
改变
b
你会让一些人大吃一惊。也许拷贝构造函数以一种外部不可见的方式更改源代码是合法的,但在这种情况下,我认为最好在常量拷贝构造函数内部使用
const\u cast

我认为错误不是关于
delete
,而是关于定义多个复制构造函数,这是不允许的。我怀疑,即使允许使用非常量复制构造函数,在语言中也有点麻烦

other.m_just = nullptr;
这一行不应该编译。您的编译器一定有问题,或者您的代码示例不能准确反映您正在编译的内容

无论如何,move构造函数应该采用非常量值引用


注释行根本不是必需的。别提了。如果您定义了复制构造函数(即使已删除),编译器也不会定义其他形式的复制构造函数,因此,如果您不使用该行,就不会有对Self进行非常量引用的构造函数,这意味着重载解析只会选择常量引用的复制构造函数,无论如何都会被删除。

编译器只会生成
Maybe(Maybe&)
Maybe(const Maybe&)

第12.8节第8段列出了选择的条件:

X
的隐式声明的复制构造函数将具有 表格
X::X(常数X&)
if

  • X
    的每个直接或虚拟基类
    B
    都有一个复制构造函数,其第一个参数的类型为
    const B&
    const volatile B&
    ,并且
  • 对于属于
    类类型M
    (或其数组)的
    X
    的所有非静态数据成员,每个此类类类型都有一个副本构造函数,其 第一个参数的类型为
    const M&
    const volatile M&
否则,隐式声明的复制构造函数将具有
X::X(X&)

或者更非正式地说,参数将是
const
当且仅当需要复制的所有内容都可以“const copy”

删除一个不会导致生成另一个


由于您没有基类,并且您的唯一成员是指针,因此生成的构造函数将是常量类型的,您可以省略导致错误的行

这是一个非常好的例子,我的意图是绝对地、真正地完全地不这样做。如中所示-我不需要任何自动生成的复制构造函数。还没有开始使用赋值运算符…
可能
可能
是同一回事,因为有一种神秘但有用的机制叫做“注入”。@KerrekSB是的-一旦出现警告,我就将它改为
可能
。我很想你主要指的是我的移动构造函数,它不是复制构造函数(至少在我看来)但是是的,我同意这很有趣,我可以在我的移动构造函数中变异const对象而没有警告和错误;)不,移动构造函数很好,我不是在说这个。这是当你取消注释那一行时得到的第二个复制构造函数,这就是问题所在。我保留了move构造函数代码以备不时之需。它编译(和运行)时没有警告,也没有我的编译器出错(在我问题的顶部给出了我的工具链)。也许我应该删除它,以免人们分心。@BitTickler啊,我现在明白了。它是模板类的成员函数,因此编译器永远不会对其进行类型检查,除非它被实例化。(MSVC在检查模板方面非常懒惰。)如果你真的试图移动一个
可能
,你会得到错误。(用更新2测试,还没有安装U3。)实际上,如果我注释掉我的move构造函数,我的代码不会编译。然而,如果我在内部的mutating语句上设置断点,它就永远不会被击中。。。现在,谁能解释呢?!:)如果没有移动构造函数,它将尝试使用复制构造函数:1>…\usingclangmaybe.cpp(225):错误C2280:'Maybe::Maybe(Maybe&'):尝试