(Я задал вариант этого вопроса на comp.std.С++, но не получил ответа.)
Почему вызов f(arg)
в этом коде вызывает перегрузку const ref из f
?
void f(const std::string &); //less efficient
void f(std::string &&); //more efficient
void g(const char * arg)
{
f(arg);
}
В моей интуиции говорится, что нужно выбрать перегрузку f(string &&)
, потому что arg
нужно преобразовать во временное значение независимо от того, что и временное совпадение с ссылкой rvalue лучше, чем ссылка lvalue.
Это не то, что происходит в GCC и MSVC (edit: Thanks Sumant: этого не происходит в GCC 4.3-4.5). По крайней мере, g++ и MSVC, любое lvalue не связывается с аргументом ссылки rvalue, даже если есть промежуточный временный созданный. В самом деле, если перегрузка const ref отсутствует, компиляторы диагностируют ошибку. Тем не менее, запись f(arg + 0)
или f(std::string(arg))
действительно выбирает опорную перегрузку rvalue, как и следовало ожидать.
Из моего чтения стандарта С++ 0x кажется, что неявное преобразование const char * в строку должно учитываться при рассмотрении, если f(string &&)
жизнеспособно, так же, как при передаче const lvalue ref аргументы. В разделе 13.3 (разрешение перегрузки) не проводится различие между rvalue ref и ссылками на const во многих местах. Кроме того, кажется, что правило, которое препятствует lvalues от привязки к rvalue-ссылкам (13.3.3.1.4/3), не должно применяться, если есть промежуточный временный - в конце концов, совершенно безопасно перемещаться из временного.
Это:
- Я неправильно читаю/неправильно понимаю стандарт, где внедренное поведение - это предполагаемое поведение, и есть ли веская причина, почему мой пример должен вести себя так, как это делается?
- Ошибка, которую разработчики компилятора каким-то образом сделали? Или ошибка, основанная на общих стратегиях реализации? Или ошибка, например. GCC (где это правило привязки ссылки lvalue/rvalue было впервые реализовано), которое было скопировано другими поставщиками?
- Неисправность в стандарте или непреднамеренное последствие или что-то, что необходимо разъяснить?
EDIT: у меня есть следующий вопрос, который связан с: С++ 0x ссылки на rvalue - привязка lvalues-rvalue