временные конструкции (я задавал вариации этого вопроса на comp.std.C++, но не получил ответа.)C++ 0x RValue ссылки и
Почему вызов f(arg)
в этом коде вызова Конст 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 (Редактировать: спасибо Sumant: этого не происходит в GCC 4.3-4.5). В по крайней мере
G ++ и
MSVC любое lvalue не связывается с аргументом ссылки rvalue, , даже если существует промежуточное временное создание. В самом деле, если перегрузка const ref отсутствует, компиляторы диагностируют ошибку. Тем не менее, запись f(arg + 0)
или f(std::string(arg))
делает выбирает ссылочную перегрузку rvalue, как и следовало ожидать.
Из моего чтения стандарта C++ 0x кажется, что неявное преобразование const char * в строку должно учитываться при рассмотрении, если f(string &&)
жизнеспособна, так же, как при передаче аргументов const lvalue ref. В разделе 13.3 (разрешение перегрузки) не проводится различие между rvalue ref и ссылками на const во многих местах. Кроме того, кажется, что правило, которое препятствует lvalues от привязки к rvalue-ссылкам (13.3.3.1.4/3), не должно применяться, если есть промежуточный временный - в конце концов, совершенно безопасно перемещаться из временного.
Является ли это:
- Me искажения/неправильно понимает стандарт, в котором реализуется поведением является предполагаемым поведением, и есть какая-то веская причина, почему мой пример должен вести себя так, как это делает?
- Ошибка, которую продавцы компилятора каким-то образом сделали? Или ошибка, основанная на общих стратегиях реализации? Или ошибка, например. GCC (где это правило привязки ссылки lvalue/rvalue было впервые реализовано), которое было скопировано другими поставщиками?
- Дефект в стандартном или непреднамеренном результате или что-то, что необходимо уточнить?
EDIT: У меня есть прослеживания на вопрос, который связан: C++0x rvalue references - lvalues-rvalue binding
В данной ситуации, почему бы перегрузка была быстрее? Строковый объект должен быть создан так или иначе и привязан к нему ссылкой. – UncleBens
@UncleBens: предположим, что функция хранит свой аргумент в некоторой глобальной переменной/членной переменной - если аргумент известен как подвижный, то он может быть перемещен в цель, а не скопирован. – Doug