Прочитайте эту статью: Появление и исчезновение констант в C ++
Вывод типа для авто переменных в C ++ 0x по сути такой же, как
для параметров шаблона. (Насколько я знаю, единственная разница
между ними то, что тип авто переменных может быть выведен из
списки инициализатора, в то время как типы параметров шаблона могут не быть.)
Поэтому каждое из следующих объявлений объявляет переменные типа
int (никогда не const int):
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
).
Редактировать: Что касается того, почему auto
выводит тип возвращаемого значения GetFoo()
в качестве значения вместо ссылки (что было вашим главным вопросом, извините), учтите следующее:
const Foo my_foo = GetFoo();
Приведенное выше создаст копию, поскольку my_foo
является значением. Если бы auto
вернул ссылку на lvalue, вышеприведенное было бы невозможно.