在运行时确定返回类型是Rvalue还是Lvalue时,如何避免不必要的复制?

时间:2019-07-05 23:35:23

标签: c++ design-patterns reference

考虑以下行

const auto x = condition ? getLvalue() : getRvalue();

因为x是const,所以我不需要复制getLvalue返回的值,如果我能引用它,我会很高兴。当然,以下内容不会编译

const auto& x = condition ? getLvalue() : getRvalue(); // Compilation error

因为引用R值没有意义。

我该如何解决这个问题?是否有问题,或者我可以只相信编译器来了解getLvalue的返回类型不需要复制吗?

1 个答案:

答案 0 :(得分:0)

有点亲密,但也许是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重载中,我增加了值,以便可以确保它仍然是引用。