当按值返回列表初始化的对象时,为什么不调用复制构造函数?
Why is the copy-constructor not called when returning by-value a list-initialized object?
我知道当对象按值从函数返回时,会调用它们的复制构造函数。如果一个类有一个已删除的复制构造函数,按值返回将失败。
struct X {
X(const X &) = delete;
};
X f() {
return X{};
}
error: call to deleted constructor of 'X'
c++ 11提供了扩展初始化式。我在某个地方读到这个
X f() {
return {};
}
与
相同X f() {
return X{};
}
那么为什么下面的代码没有给我一个错误呢?它通过了,我甚至可以调用main中的函数:
struct D {
D(const D &) = delete;
};
D f() { return {}; }
int main()
{
f();
}
这里是一个演示。无错误报告。我觉得这很奇怪,因为我认为应该调用复制构造函数。谁能解释一下为什么没有错误?
我在某个地方读到这篇文章[…][…]与[…]相同
他们错了。它们相似,但不相同。
通过使用带括号的init-list,您可以初始化返回值就地。如果你创建了一个临时变量,那么你所做的就是创建这个临时变量,然后将它复制到返回值中。任何称职的编译器都会忽略它,但是复制构造函数仍然必须是可访问的。
但是,由于大括号init-list会就地初始化返回值,因此不需要访问复制构造函数。
出自标准第6.6.3节p2:
带带括号的init-list的return语句,通过copy-list-initialization(8.5.4)从指定的初始化列表初始化要从函数返回的对象或引用。
注意"copy-list-initialization"与"copy-initialization"不同;它不做任何复制,因此不需要一个可访问的复制构造函数。"copy-list-initialization"answers"direct-list-initialization"的唯一区别是前者会阻塞explicit
构造函数。
相关文章:
- 为什么不调用移动构造函数?(默认情况下只有构造器,没有别的)
- C++ 基本 CTOR 说明 - 为什么不调用赋值/复制构造函数
- C++:为什么不调用移动构造函数?
- 为什么不调用移动构造函数
- 类继承自QLabel,为什么不调用自定义插槽?
- 为什么不调用预期的函数?我是否对类型特征的理解不正确?
- 为什么不调用虚拟基非默认构造函数,除非大多数派生基显式调用它们?
- 为什么不调用全局静态变量的析构函数
- 为什么不调用模板类中的转换构造函数?
- 为什么不调用基类 2 的构造函数
- 为什么当对象构造函数投入新表达式时,为什么不调用DealLocation函数
- 为什么不调用构造函数?
- 为什么不调用复制构造函数,但在此代码中调用默认构造函数
- 为什么不调用移动构造函数?
- 移动语义,为什么不调用移动构造函数
- 为什么不调用私有成员的默认构造函数
- 为什么不调用这个 Ruby 覆盖方法
- 为什么不调用该函数?C++
- 为什么不调用 std::string move 构造函数?
- 为什么不调用移动构造函数?