0

我有一个树类,它声明和定义了移动构造函数和移动赋值运算符。

为什么编译器会觉得需要合成一个复制构造函数,然后抱怨std::unique_ptr有私有成员?

这似乎适得其反。编译器是否应该不知道没有正文或根本未定义的隐藏副本和赋值是为了防止尝试复制 a std::unique_ptr

而且,为什么用空主体声明和定义复制构造函数和赋值运算符会使编译器高兴?

当我继续使用这个类编写和构建代码时,这是否会引起关注?

补充

  1. 没有源代码,因为没有源代码错误……这是一个
    不需要源代码存在的问题。

  2. 当复制构造函数是私有的时编译器会抱怨,所以我将它们公开;将再次设为私有并验证编译器是否存在问题。

  3. 我正在使用 Visual Studio 2012 Professional IDE 及其相关的编译器。

为什么编译器在存在移动构造函数的情况下生成复制构造函数?似乎违反直觉,特别是如果没有在第一处定义复制构造函数。

附加问题

好吧,Visual Studio 2012 似乎不支持 = delete 构造函数或赋值运算符的声明,隐藏我的声明会导致编译器在我的代码中哭泣。现在我该怎么做?我同意(如下)声明不做任何事情的复制构造函数是个坏主意,那么我还有什么其他选择?

如果真的想要小例子,这里就是。我的编译器不支持 = delete

class Tree{
    class TreeNode{
         "declaration of unique_ptr, cstrs, move cstrs, hidden copy cstrs"
    };
public:
     "declaration of unique_ptrs, cstrs, move cstrs, copy cstrs <----- compiler 
      complains if hidden"
};

对此使用 boost::variant

4

2 回答 2

2

如果没有复制构造函数,编译器将尝试生成一个。默认的复制构造函数非常愚蠢,因此它会绊倒您的类的一些部分也就不足为奇了。

定义一个空的会为您提供一个不执行任何操作的复制构造函数,它会替换编译器原本会生成的复制构造函数,从而避免了该问题。

于 2013-03-28T12:04:25.250 回答
1

为什么编译器会觉得需要合成一个复制构造函数,然后抱怨std::unique_ptr有私有成员?

它不应该,除非你的标准库是不兼容的,并且声明一个私有的而不是删除的复制构造函数unique_ptr; 即便如此,只有在您没有声明移动构造函数时才应该合成它。

如果你的类有unique_ptr成员,或者如果你声明了一个移动构造函数,那么它应该抱怨复制构造函数被删除;然后仅当您编写尝试复制它的代码时。

编译器是否应该不知道没有正文或根本未定义的隐藏副本和赋值是为了防止尝试复制 a std::unique_ptr

这是正确的; 除了合成的复制构造函数和赋值被删除,而不是未定义。

而且,为什么用空主体声明和定义复制构造函数和赋值运算符会使编译器高兴?

因为您明确表示您希望它使用该(空)代码进行复制,而不是它可能(或可能不会)隐式生成的任何代码。不过这是个坏主意;如果您的类不可复制,那么您希望尝试复制它以生成错误,而不是不正确的运行时行为。

于 2013-03-28T12:18:52.103 回答