在运行时决定返回类型是右值还是左值时,如何避免不必要的复制?
Posted
技术标签:
【中文标题】在运行时决定返回类型是右值还是左值时,如何避免不必要的复制?【英文标题】:How to avoid unnecessary copying when whether the return type is a Rvalue or an Lvalue is decided at run time? 【发布时间】:2019-11-16 12:09:33 【问题描述】:考虑下面一行
const auto x = condition ? getLvalue() : getRvalue();
因为x
是const,我不需要复制getLvalue
返回的值,如果我能引用它我会很高兴。当然,以下不会编译
const auto& x = condition ? getLvalue() : getRvalue(); // Compilation error
因为引用 R 值是没有意义的。
我该如何解决这个问题?有问题还是我可以相信编译器理解getLvalue
的返回类型不需要复制?
【问题讨论】:
你试过const auto&& x = ...
吗?
我们称 && 为通用参考。也许有点过时但值得一读here
您可以使用std::move(getLvalue())
。
@AlexHodges 你确定这会有所帮助吗?无论如何,条件表达式的值类别是固定的,所以通用引用对 AFAIK 没有帮助 ...
通用引用将成为左值或右值,具体取决于它的初始化内容。由于您的参考可以是 l 或 r,因此使用通用参考似乎很合适,然后 std::forward 到任何需要参考的地方。
【参考方案1】:
有点接近,但也许是std::variant<T, std::reference_wrapper<T>>
?
您不能真正使用三元运算符进行赋值,因为它需要 std::common_type
,但它适用于常规 if...else
:
Demo(需要 C++17)
代码:
int choice = 0;
std::cin >> choice;
std::variant<int, std::reference_wrapper<int>> opt;
if (choice == 0)
opt = getRValue();
else
opt = std::ref(getLValue());
getRValue()
和 getLValue()
的存根:
int& getLValue()
static int foo = 42;
return foo;
int getRValue()
return 1337;
我们可以访问变体进行打印:
struct visitor
void operator()(int _val)
std::cout << "rvalue value: " << _val;
void operator()(std::reference_wrapper<int> _val)
std::cout << "reference_wrapper value: " << _val << std::endl;
_val += 1;
;
在reference_wrapper
重载中,我增加了值,以便我们可以确定它仍然是一个引用。
【讨论】:
以上是关于在运行时决定返回类型是右值还是左值时,如何避免不必要的复制?的主要内容,如果未能解决你的问题,请参考以下文章