隐式与显式删除的复制构造函数

时间:2013-12-02 12:09:31

标签: c++ c++11

我最近在C ++ 11代码中遇到了一些奇怪的行为。

我有一个班级,只能移动:

class only_move
{
public:

    only_move() :  value(0) {}

    only_move(int value) : value(value) {}

    only_move(const only_move&) = delete;
    only_move& operator=(const only_move&) = delete;

    only_move(only_move&&) = default;
    only_move& operator=(only_move&&) = default;

    int value;
};

我还有另一个类,其中包含一个only_move对象:

class has_only_move_member
{
public:

    has_only_move_member() = delete;

    has_only_move_member(only_move&& value) : member(std::move(value)) {}

    only_move member;
};

如果我理解正确,则表示无法复制has_only_move_member,因为only_move成员无法复制。这意味着隐式删除has_only_move_member(const has_only_move_member&)。我们来看看:

has_only_move_member object(only_move(5));
has_only_move_member copy_of_object(object);

正如所料,它打印出来:

error: use of deleted function ‘has_only_move_member::has_only_move_member(const has_only_move_member&)’
note: ‘has_only_move_member::has_only_move_member(const has_only_move_member&)’ is implicitly deleted because the default definition would be ill-formed:
class has_only_move_member

好的,我继续将has_only_move_member个实例放在std::map中。由于他们没有复制构造函数,我已将它们移入其中:

has_only_move_member object(only_move(5));

std::map<int, has_only_move_member> data;
data.emplace(5, std::move(object));

到目前为止一切顺利。这就像一个魅力。

但我有个主意。如何更明确地删除has_only_move_member的复制构造函数。所以我写了课has_only_move_member

has_only_move_member(const has_only_move_member&) = delete;

之后,从上面的相同代码,我将对象移动到地图中给了我一个错误:

/usr/include/c++/4.8/bits/stl_pair.h:134:45: error: use of deleted function ‘has_only_move_member::has_only_move_member(const has_only_move_member&)’

是的,它当然被删除了,但为什么隐式和显式删除之间存在这样的差距?

我在使用libstdc ++的Debian上使用g ++ 4.8.2和clang 3.4-rc1以及使用libc ++的Mac OS X 10.9上最近的apple-clang-llvm 4.0获得相同的行为

1 个答案:

答案 0 :(得分:10)

我已在评论中说过这一点,但由于这是一个正确答案,我将其作为一个回复:

您添加了一个自定义构造函数(即使它是已删除的构造函数)。因此编译器不会自动生成移动构造函数。编译器然后回退到复制哪个(按照你的要求)它显然不能做。