我们可以通过函数的值返回具有已删除/私有复制/移动构造函数的对象吗?

Joh*_*itb 16 c++ copy-constructor c++11

在C++ 03中,不可能通过值返回具有私有非定义复制构造函数的类的对象:

struct A { A(int x) { ... } private: A(A const&); };

A f() {
  return A(10); // error!
  return 10;    // error too!
}
Run Code Online (Sandbox Code Playgroud)

我想知道,这个限制是否在C++ 11中解除了,是否可以编写具有类类型返回类型的函数,而没有用于复制或移动的构造函数?我记得允许函数的调用者使用新返回的对象可能很有用,但是他们无法复制值并将其存储在某处.

Joh*_*itb 14

以下是它的工作原理

A f() {
  return { 10 };
}
Run Code Online (Sandbox Code Playgroud)

这工作即使A没有工作副本或移动构造函数,也没有其他可以复制或移动的构造函数A!

为了利用C++ 11的这个特性,构造函数(int在这种情况下)必须是非显式的.

  • 你和你的测验问题.:( (2认同)

How*_*ant 5

上面的代码在 C++11 中仍然是格式错误的。但是你可以添加一个公共移动构造函数A,然后它就合法了:

struct A
{
    A(int x) {}
    A(A&&);
private:
    A(A const&);
};

A f() {
  return A(10); // Ok!
}
Run Code Online (Sandbox Code Playgroud)


Dav*_*eas 5

该限制尚未取消.根据访问说明符,§12.8/ 32中有一条说明解释:

无论是否发生复制省略,都必须执行两级重载决策.如果未执行elision,它将确定要调用的构造函数,并且即使调用被省略,也必须可以访问所选的构造函数.

截至删除的复制/移动构造函数§8.4.3/ 2表明

除了声明它之外,隐式或显式引用已删除函数的程序是不正确的.[注意:这包括隐式或显式调用函数并形成指向函数的指针或指向成员的指针.它甚至适用于未进行潜在评估的表达式中的引用.如果函数重载,则仅在通过重载决策选择函数时才引用它. - 结束说明]

不确定这个特殊情况,但我对引用的理解是,如果在§12.8/ 32中的重载解析之后选择了删除的复制/移动构造函数,即使操作被省略,也可能构成对函数的引用,该计划将形成不良.