[英]Why is the copy-constructor not called when returning by-value a list-initialized object?
I understand that when objects are returned by-value from a function, their copy-constructors are called. 据我所知,当从函数返回-value对象时,会调用它们的copy-constructors。 If a class has a deleted copy-constructor, returning by value will fail. 如果类具有已删除的复制构造函数,则按值返回将失败。
struct X {
X(const X &) = delete;
};
X f() {
return X{};
}
error: call to deleted constructor of 'X'
C++11 gives us extended-initializers. C ++ 11为我们提供了扩展初始化器。 And I read somewhere on a SO post that this 我在SO帖子的某个地方读到了这个
X f() {
return {};
}
is the same as 是相同的
X f() {
return X{};
}
So why doesn't the below code give me an error? 那么为什么下面的代码没有给我一个错误? It passes and I even get to call the function in main: 它通过了,我甚至可以在main中调用该函数:
struct D {
D(const D &) = delete;
};
D f() { return {}; }
int main()
{
f();
}
Here is a demo. 这是一个演示。 No error is reported. 没有报告错误。 I find that weird because I believe that the copy-constructor should be called. 我发现这很奇怪,因为我认为应该调用copy-constructor。 Can anyone explain why no error is given? 任何人都可以解释为什么没有给出错误?
And I read somewhere on a SO post that this [...] is the same as [...] 我在SO帖子上的某个地方读到这个[...]与[...]相同
They were wrong. 他们错了。 They're similar , but not the same. 它们相似 ,但不一样。
By using the braced-init-list, you are able to initialize the return value in-place . 通过使用braced-init-list,您可以就地初始化返回值。 If you create a temporary, then what you're doing is creating the temporary and then copying it into the return value. 如果你创建一个临时的,那么你正在做的是创建临时,然后将其复制到返回值。 Any compiler worth its salt will elide it, but the copy constructor still must be accessible. 任何值得盐的编译器都会忽略它,但复制构造函数仍然必须是可访问的。
But since the braced-init-list initializes the return value in-place, you don't need access to the copy constructor. 但由于braced-init-list就地初始化返回值,因此您不需要访问复制构造函数。
From the standard, section 6.6.3, p2: 从标准6.6.3节,p2:
A return statement with a braced-init-list initializes the object or reference to be returned from the function by copy-list-initialization (8.5.4) from the specified initializer list. 带有braced-init-list的return语句通过copy-list-initialization(8.5.4)从指定的初始化列表初始化要从函数返回的对象或引用。
Note that "copy-list-initialization" is not similar to "copy-initialization"; 注意,“copy-list-initialization”与“copy-initialization”不同; it doesn't do any copying and therefore it doesn't require an accessible copy constructor. 它不进行任何复制,因此它不需要可访问的复制构造函数。 The only difference between "copy-list-initialization" and "direct-list-initialization" is that the former will choke on explicit
constructors. “复制列表初始化”和“直接列表初始化”之间的唯一区别是前者会阻塞explicit
构造函数。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.