C++11 auto: что делать, если он получает постоянную ссылку?
пожалуйста, взгляните на следующий простой код:
class Foo
{
public:
Foo(){}
~Foo(){}
Foo(const Foo&){}
Foo& operator=(const Foo&) { return *this; }
};
static Foo g_temp;
const Foo& GetFoo() { return g_temp; }
Я пытался использовать auto
такой:
auto my_foo = GetFoo();
Я ожидал, что my_foo
будет постоянной ссылкой на Foo
, который является возвращаемым типом функции. Однако, тип auto
- это Foo
, а не ссылкой. Кроме того, my_foo
создается путем копирования g_temp
. Это поведение не так очевидно для меня.
чтобы получить ссылку на Foo
, мне нужно напишите вот так:
const auto& my_foo2 = GetFoo();
auto& my_foo3 = GetFoo();
вопрос: почему auto
вывести возвращаемый тип GetFoo
как объект, а не ссылка?
1 ответ:
читать эту статью: появление и исчезновение запоров В C++
тип вычета для автоматических переменных в C++0x по существу такой же, как для параметров шаблона. (Насколько я знаю, Единственная разница между ними заключается в том, что тип автоматических переменных может быть выведен из списки инициализации, в то время как типы параметров шаблона не может быть.) Поэтому каждое из следующих объявлений объявляет переменные типа инт (не константный инт):
auto a1 = i; auto a2 = ci; auto a3 = *pci; auto a4 = pcs->i;
во время вычета типа для параметров шаблона и автоматических переменных, только запоры верхнего уровня удаляются. Данный шаблон функции, принимая указатель или параметр ссылки, константа того, что указано или ссылка сохраняется:
template<typename T> void f(T& p); int i; const int ci = 0; const int *pci = &i; f(i); // as before, calls f<int>, i.e., T is int f(ci); // now calls f<const int>, i.e., T is const int f(*pci); // also calls f<const int>, i.e., T is const int
это поведение является старой новостью, применяясь как к C++98, так и C++03. Соответствующее поведение для автоматических переменных, конечно, новое C++0x:
auto& a1 = i; // a1 is of type int& auto& a2 = ci; // a2 is of type const int& auto& a3 = *pci; // a3 is also of type const int& auto& a4 = pcs->i; // a4 is of type const int&, too
поскольку вы можете сохранить CV-квалификатор, если тип является ссылкой или указателем, вы можете сделать:
auto& my_foo2 = GetFoo();
вместо того, чтобы указывать его как
const
(то же самое дляvolatile
).Edit: а почему
auto
выводит возвращаемый типGetFoo()
в качестве значения вместо ссылки (что было вашим главным вопросом, Извините), рассмотрим это:const Foo my_foo = GetFoo();
выше будет создана копия, так как
my_foo
- это ценность. Еслиauto
должны были вернуть ссылку lvalue, выше не было бы возможно.