ли я понимаю, что знание о том, является ли выражение prvalue или xvalue неважно для программиста? Ну, то есть понимание того, как видит выражение компилятор помогает понять, что с данными будет происходить потом, но у программиста нет никакого способа выбрать, как передать куда-то ОДИН И ТОТ ЖЕ объект: как prvalue или xvalue (и в зависимости от этого изменить поведение программы).
Грубо говоря, если это prvalue, то как не кастуй к xvalue, ты из него xvalue не сделаешь. А если обратился к мемберу prvalue, то получилось xvalue и его к prvalue тоже уже не прикастуешь (любая подобная попытка приведёт к созданию временного объекта).
Выходит, что если передача в функцию lvalue и rvalue это вполне себе различимые вещи, то передача prvalue и передача xvalue это одно и то же. То есть есть просто передача rvalue. Но она имеет настолько сложные правила, что для удобства свойства половины случаев описываются, как подкатегория.
Максимум, что мы можем - это задектетить, как что-то передавалось (по вызовам copy и move конструкторам или спросив type_traits от decltype() выражения. Но вмешаться в этот процесс мы никак не можем (заставить кастами prvalue отработать как будто это xvalue или наоборот).
Читали вчера обсуждение? const T & t = static_cast<T &&>(T{}); - prvalue чудесным образом превращается в xvalue. С точки зрения передачи в функцию или инициализации разницы между видами rvalue вроде нет.
Обсуждают сегодня