提问人:TwistedBlizzard 提问时间:8/30/2023 最后编辑:TwistedBlizzard 更新时间:8/30/2023 访问量:42
编译器可以省略特定数据成员的副本吗?
Can the compiler elide copies of specific data members?
问:
获取此代码:
struct Bar { //has non-default copy-constructor
Bar() = default;
Bar(const Bar&) {}
};
struct LargeObject { //has default copy-constructor
std::array<char, 1000> m_chars;
};
struct Foo {
Bar m_bar;
LargeObject m_obj;
};
Foo func() { Foo f; return f; }
当用户指定复制构造函数时,编译器无法省略副本。当类的成员具有非默认复制构造函数时,该怎么办?在这段代码中,当从 返回时,编译器可以省略 的副本还是必须复制所有内容?f
func
m_obj
答:
3赞
ShadowRanger
8/30/2023
#1
你的问题是基于一个错误的前提。编译器完全有权省略这样的副本,无论类本身或其成员之一是否具有非默认的复制(或移动)构造函数。自 C++ 11 以来引入的复制省略规则的好处是允许这种优化,即使它违反了假设规则。
如果它不能做到这一点,那么复制省略就不会那么有用;即使具有单个智能指针(具有自定义复制和移动构造函数)的类也不符合 RVO 的条件,除非编译器可以肯定地证明没有违反假设规则。
在特定方案中,编译器通常可以通过直接将对象构造到调用方提供的存储中来实现(并且启用优化后,这不是强制性的,因为您依赖于非强制性 NRVO,而不是简单 RVO 的 C++17 保证复制省略)来实现,而无需使用必须移动/复制回调用方的单独对象。func
Foo
Foo f
评论
Foo
Foo
Foo
Foo
Foo