一个私有的移动构造函数可以防止移动吗?

11

在C++中常见的一种模式是将复制构造函数设为私有:

class A
{
    public:
        // ...
    private:
        A(const A&);
};

但是以下代码是否能够在 C++11/14 中编译:

A f();

auto a = f();

这个标准包含有关自动生成移动构造函数的信息。我既没有访问该标准的权限,也没有能够实际生成移动构造函数的编译器。我的问题是:我是否必须编写

class A
{
    public:
        // ...
    private:
        A(const A&);
        A(const A&&);
};

是否同样要防止移动 (并且操作符= 的行为也类似)?


1
如果你编写了一个复制构造函数,它不会生成移动构造函数。 - Marc Glisse
2
用户声明的复制构造函数会阻止移动成员的生成。 - Xeo
3
请注意,您所提到的模式适用于C++98/03,但现在在C++11中已被弃用,因为可以使用delete构造函数/赋值运算符(例如, ClassName(ClassName &&)= delete; )显式防止隐式移动构造函数。 - syam
syam: 你说得对。我使用旧模式的原因是(i)我的编译器不支持它,(ii)我特别关注C++98代码在C++11下的行为。 - Petter
我想我应该相信 C++11 不会引入这样的意外。一切都如期进行。 - Petter
1个回答

15
以下代码在C++11/14下是否能编译通过?
不行。存在用户声明的复制构造函数将禁止隐式生成移动构造函数。根据C++11标准第12.8/9段:
如果类X的定义没有显式声明移动构造函数,那么只有在以下情况下才会隐式声明为默认值:
- X没有用户声明的复制构造函数, - X没有用户声明的复制赋值运算符, - X没有用户声明的移动赋值运算符, - X没有用户声明的析构函数,并且 - 移动构造函数不会被隐式定义为已删除。

太棒了!我再次被SO惊艳到了! :-) - Petter

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接