Я хотел бы добавить, что вы можете настраивать пользовательские функции-члены, такие как ++
, которые ведут себя по-разному при вызове через ссылки lvalue и rvalue. Например, вы можете определить пользовательский класс iterator
, который не позволяет вам временно вызывать модифицирующие функции-члены. Для этого вам необходимо использовать ссылочные квалификаторы .
class iterator {
public:
iterator operator++() & { // for lvalues
std::cout << "incrementing...\n";
}
iterator operator++() && = delete; // for rvalues
};
С этими квалификаторами вы все еще можете изменять lvalues:
iterator it = ...;
++it; // totally fine
, но теперь вы можете предотвратить изменение временных значений, что приведет к созданию пользовательского класса, более совместимого со встроенными типами, такими как size_t
.
++(iterator{}); // ERROR
Живой пример здесь
Я не уверен, что стандарт говорит об этом для типа итератора std::string
, но в принципе, вы можете сделать это для своих собственных итераторов и других классов, где бы вы ни думали, что модификация временного всегда является ошибкой .