问题描述
请考虑以下程序:
#include<iostream>
using namespace std;
struct S
{
S() = default;
S(const S& other) = delete;
S(S&& other) = delete;
int i;
};
S nakedBrace()
{
return {}; // no S constructed here?
}
S typedBrace()
{
return S{};
}
int main()
{
// produce an observable effect.
cout << nakedBrace().i << endl; // ok
cout << typedBrace().i << endl; // error: deleted move ctor
}
示例会话:
$ g++ -Wall -std=c++14 -o no-copy-ctor no-copy-ctor.cpp
no-copy-ctor.cpp: In function 'S typedBrace()':
no-copy-ctor.cpp:19:12: error: use of deleted function 'S::S(S&&)'
return S{};
^
no-copy-ctor.cpp:8:5: note: declared here
S(S&& other) = delete;
令我惊讶的是,gcc接受 nakedBrace()
。我认为这两个函数在概念上是等价的:构造并返回一个临时 S
。复制精度可以执行也可以不执行,但是移动或复制ctor(两者都在此处删除)必须仍然可以访问,如标准(12.8 / 32)所要求的。
It astonishes me that gcc accepts nakedBrace()
. I thought that conceptually the two functions are equivalent: A temporary S
is constructed and returned. Copy elision may or may not be performed, but the move or copy ctor (both are deleted here) must still be accessible, as mandated by the standard (12.8/32).
这是否意味着 nakedBrace()
从不构造S?或者它,但直接在返回值与大括号初始化,所以没有复制move / ctor在概念上需要?
Does that mean that nakedBrace()
never constructs an S? Or it does, but directly in the return value with brace-initialization, so that no copy move/ctor is conceptually required?
推荐答案
这是标准的行为。
这意味着 nakedBrace
和 typedBrace
等效于以下内容:
This means that the initializations carried out by nakedBrace
and typedBrace
are equivalent to these:
S nakedBrace = {}; //calls default constructor
S typedBrace = S{}; //calls default, then copy constructor (likely elided)
这篇关于返回临时类型,删除移动/复制ctor的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!