【问题标题】: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 到任何需要参考的地方。

标签: c++ design-patterns reference


【解决方案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 重载中,我增加了值,以便我们可以确定它仍然是一个引用。

【讨论】:

    猜你喜欢
    • 2014-03-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-03
    • 1970-01-01
    • 2023-03-08
    相关资源
    最近更新 更多