Как избежать ненужного копирования, если во время выполнения определяется тип возвращаемого значения: Rvalue или Lvalue? - PullRequest
3 голосов
/ 06 июля 2019

Рассмотрим следующую строку

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

Поскольку x является константой, мне не нужно копировать значение, возвращаемое getLvalue, я был бы рад, если бы я мог просто взять ссылку на него. Конечно, следующее не скомпилирует

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

, поскольку нет смысла ссылаться на значение R.

Как мне обойти эту проблему? Есть ли проблема или я могу просто доверить компилятору понять, что возвращаемый тип getLvalue не требует копирования?

1 Ответ

0 голосов
/ 06 июля 2019

Вид закрытия, но, возможно, std::variant<T, std::reference_wrapper<T>>?

Вы не можете использовать троичный оператор для назначения, потому что для этого требуется std::common_type, но он отлично работает для обычных if...else:

Демо (требуется 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 я увеличиваю значение, чтобы мы могли быть уверены, что оно все еще является ссылкой.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...