Пытаюсь окончательно разобраться с безопасным и быстрым возвратом тяжелых объектов. Правильно ли я понимаю принцип, или можно короче? Есть явные ляпы и ошибки?
Полностью понятный и комплексный пример мне нагуглить не удалось, поэтому обращаюсь к гуру:
#include <iostream>
#include <vector>
#include <string>
struct very_huge_but_fast_movable
{
void print() const& { std::cout << "size: " << data.size() << " const&\n"; }
void print() const&& { std::cout << "size: " << data.size() << " const&&\n"; }
void print() & { std::cout << "size: " << data.size() << " &\n"; }
void print() && { std::cout << "size: " << data.size() << " &&\n"; }
std::vector<int> data = std::vector<int>(1000);
};
struct carier
{
const very_huge_but_fast_movable& get_huge() const& { return m_some; }
const very_huge_but_fast_movable&& get_huge() const&& { return std::move(m_some); }
very_huge_but_fast_movable& get_huge() & { return m_some; }
very_huge_but_fast_movable&& get_huge() && { return std::move(m_some); }
very_huge_but_fast_movable m_some;
};
int main()
{
const carier cstate;
cstate.get_huge().print();
const_cast<const carier&&>(carier()).get_huge().print();
carier state;
state.get_huge().print();
carier().get_huge().print();
return 1;
}
size: 1000 const&
size: 1000 const&&
size: 1000 &
size: 1000 &&
Здравствуйте, Videoman, Вы писали:
V>Пытаюсь окончательно разобраться с безопасным и быстрым возвратом тяжелых объектов. Правильно ли я понимаю принцип, или можно короче? Есть явные ляпы и ошибки?
Можно озвучить проблему целиком ?
Здравствуйте, Videoman, Вы писали:
V>Пытаюсь окончательно разобраться с безопасным и быстрым возвратом тяжелых объектов. Правильно ли я понимаю принцип, или можно короче? Есть явные ляпы и ошибки?
Есть один нюансик.
Вот такое использование продлевает время жизни подобъекта m_some до выхода из текущего блока:
auto&& huge = carier{}.m_some;
Тогда как вот такое использование создает "битую" ссылку:
auto&& huge = carier{}.get_huge();
И самое печальное то, что при помощи функций-членов (геттеров) нет возможности получить поведение, равноценное прямому доступу к члену-данному. Но если возвращаемый тип действительно имеет легковесное перемещение, то, возможно, имеет смысл вместо rvalue ссылок возвращать объект по значению. В этом случае появляется дополнительное перемещение, но становится меньше возможностей получения невалидных ссылок.
Здравствуйте, rg45, Вы писали:
А можно еще вопрос тогда, а если так сделать:
auto& huge = carier{}.m_some; // ?
// или
const auto& huge = carier{}.m_some; // ?
Здравствуйте, Videoman, Вы писали:
V>А можно еще вопрос тогда, а если так сделать:V>auto& huge = carier{}.m_some; // ?
V>// или
V>const auto& huge = carier{}.m_some; // ?
V>
Второй вариант — норм — временный объект можно биндить к константной lvalue ссылке и время жизни объекта также продлевается. А первый вариант не скомпилится — биндить временный объект к некоснстантной lvalue сслыке нельзя.