gpt4 book ai didi

c++ - 诱导编译器避免/触发右值复制

转载 作者:行者123 更新时间:2023-11-28 04:12:52 25 4
gpt4 key购买 nike

在下面的代码中,我有一个函数 foostd::function 作为参数返回一个大对象(这里是一个 vector)并仅使用它来访问其值。大对象可以由 fun 即时构建,也可以是对现有对象的引用,如主要节目中的两个 lambda 表达式。

我想通过选择 std::function 的正确返回类型来优化此代码以避免无用的拷贝。

如果我使用按值返回,RVO 优化拷贝并为“即时构建”情况制作我想要的:没有完成任何拷贝, vector 在它需要的地方准确构建,然后销毁在 foo 的末尾。但是,在第二种情况下,即使我真的不需要它,编译器也会复制 vector 。第二种情况是通过引用返回的完美情况,但这会破坏第一种情况,因为引用临时是邪恶的。

我知道让 foo 直接引用 vector 可以解决这个特殊情况下的问题,但我的用例更复杂。有办法解决吗?

#include <vector>
#include <iostream>
#include <functional>

struct myVec : public std::vector<double> {
using std::vector<double>::vector;
myVec(myVec const & v){
std::cout << "Copy ctor\n";
*this=v;
}
};


void foo(std::function<myVec(void)> fun){
for(auto & v : fun()){
std::cout << v << " ";
}
std::cout<<std::endl;
}

int main() {
foo([]()->myVec{return myVec(100,0.);});
myVec existing(100,1.);
foo([&existing]()->myVec{return existing;});
return 0;
}

最佳答案

[&existing]()->myVec{return existing;}通过拷贝返回,而不是通过引用返回,因此它会创建拷贝。

你需要这样[&existing]()->myVec&{return existing;} .

然后问题是std::function

所以要么提供 2 个重载(void foo(std::function<myVec()>)void foo(std::function<myVec&()>)),要么使用模板并去掉 std::function:

template <typename F>
void foo(F fun){
for (const auto & v : fun()){
std::cout << v << " ";
}
std::cout<<std::endl;
}

关于c++ - 诱导编译器避免/触发右值复制,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57300190/

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