Почему as_const запрещает аргументы rvalue?
Я хотел спросить, почему as_const
запрещает аргументы rvalue, в соответствии с cppreference.com(то есть, почему люди Стандартов сделали это так, не потому, что cppreference.com специально цитировал их на этом. А также не там, где в спецификации намерение комитета кодифицировано, просто для того, чтобы убедиться:))). Этот (искусственный) пример даст ошибку (пользователь хочет сделать его const, чтобы сохранить COW тихим)
QChar c = as_const(getQString())[0];
Еще один ответ на вопрос отмечает, что если мы просто удалим удаление ссылочной перегрузки rvalue, он будет молча преобразовывать значения rvalues в lvalues. Правильно, но почему бы не обрабатывать rvalues грациозно и возвращать const rvalues для ввода rvalue и const lvalues для ввода lvalue?
Ответы
Ответ 1
Одной из причин может быть то, что это может быть опасно для rvalues из-за отсутствия прав собственности.
for (auto const &&value : as_const(getQString())) // whoops!
{
}
и что не может быть убедительного случая использования, чтобы оправдать игнорирование этой возможности.
Ответ 2
Проблема заключается в том, чтобы обрабатывать расширение продолжительности жизни
const auto& s = as_const(getQString()); // Create dangling pointer
QChar c = s[0]; // UB :-/
Возможна следующая перегрузка (вместо удаленной)
template< typename T >
const T as_const(T&& t) noexcept(noexcept(T(t)))
{
return t;
}
который предполагает дополнительную конструкцию и, возможно, другие подводные камни.
Ответ 3
Поскольку as_const не принимает аргумент в качестве ссылки на константу.
Ссылки, не связанные с константой, не могут привязываться к временным.
Упоминание экспедиторской перегрузки явно удалена.