2017-01-19 5 views
2

Я изучаю, является ли возвращение ссылки rvalue из rvalue ref-qualifier функцией действительно хорошей идеей. Допустим, мы имеем:Должен ли rvalue ссылочный ссылочный ссылочный ссылочный ссылочный номер rvalue?

class DataPack { 
public: 
    std::vector<int> data; 

    DataPack(std::initializer_list<int> d) : data{d} {} 

    std::vector<int>& get_data() & { 
    return data; 
    } 
    std::vector<int>&& get_data() && { 
    return std::move(data); 
    } 
    // This version fixes for-loop problem (see below) 
    //std::vector<int> get_data() && { 
    // return data; 
    //} 
}; 

тогда, если я хочу, чтобы получить данные без временного я могу использовать следующее:

auto my_data = DataPack{1,2,3}.get_data(); 

но предположим, что я хочу использовать следующий код:

for (auto v : DataPack{1,2,3}.get_data()) { 
    std::cout << v << ", "; 
} 

теперь это UB, поскольку get_data() возвращает ссылку на временную, которая уничтожается после полного утверждения.

Возможно, это может быть как-то зафиксировано для таких циклов? Или, может быть, нам стоит вернуться по цене и надеяться, что RVO будет работать так, как ожидалось? Похоже, что это так, как мне кажется, не очень безопасно.

+2

Почему у вас даже есть 'get_data()' в первую очередь? Просто использовать 'data' будет достаточно. Но да, вы хотели бы вернуться по стоимости. –

+0

Я не вижу UB. Может ли кто-нибудь указать, почему это UB? 'DataPack' на самом деле не выведен. –

+0

@ FrançoisAndrieux: Internally 'for' захватывает выражение диапазона с помощью' auto && ', поэтому оно превращается в' auto && __expr = DataPack {1,2,3} .get_data() '. Проблема в том, что в конце этого выражения 'DataPack' уничтожается, поэтому' __expr' становится оборванной ссылкой. – ildjarn

ответ

4
std::vector<int>&& get_data() && { 
    return std::move(data); 
} 

Это должно возвращать std::vector<int> вместо этого, то нет никаких проблем.

Смежные вопросы