gpt4 book ai didi

c++ - 为什么我不能通过 std::tuple 获得保证的复制省略?

转载 作者:行者123 更新时间:2023-12-01 13:55:20 24 4
gpt4 key购买 nike

我希望在 C++20 中,以下代码在 A 和 B 的打印之间不打印任何内容(因为我希望保证 RVO 启动)。但输出是:

A

Bye

B

C

Bye

Bye


因此,大概正在创建一个临时对象。
#include <iostream>
#include <tuple>
struct INeedElision{
int i;
~INeedElision(){
std::cout << "Bye\n";
}
};

std::tuple<int, INeedElision> f(){
int i = 47;
return {i, {47}};
}

INeedElision g(){
return {};
}

int main()
{
std::cout << "A\n";
auto x = f();
std::cout << "B\n";
auto y = g();
std::cout << "C\n";
}
这种行为的原因是什么?
是否有避免复制的解决方法(不使用指针)?
https://godbolt.org/z/zasoGd

最佳答案

构建时std::tuple<int, INeedElision>来自 {i, {47}} , the selected constructor of std::tuple 通过左值引用获取元素 const .

tuple( const Types&... args );

然后当使用 {i, {47}}作为初始值设定项,临时 INeedElision将被构造然后传递给 std::tuple 的构造函数(并被复制)。临时对象将立即销毁,您将在“A”和“B”之间看到“Bye”。
顺便说一句: std::tuple 的第三个构造函数不会用于这种情况。
template< class... UTypes >
tuple( UTypes&&... args );

它是一个构造函数模板,和类似 {47} 的花括号初始化列表没有类型并且不能通过模板参数推导来推导。
另一方面,如果 INeedElision有一个转换构造函数采用 int ,并将初始化程序设为 {i, 47} , std::tuple 的第三个构造函数将被使用并且没有临时 INeedElision已建成;该元素将从 int 就地构建 47 .
LIVE

关于c++ - 为什么我不能通过 std::tuple 获得保证的复制省略?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63560015/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com