Ответ 1
Прочтите эту статью: Появление и исчезновение констант в С++
Вывод типа для автоматических переменных в С++ 0x по существу такой же, как для параметров шаблона. (Насколько я знаю, единственная разница между ними состоит в том, что тип автоматических переменных можно вывести из списки инициализаторов, в то время как типы параметров шаблона могут отсутствовать.) Поэтому каждая из следующих деклараций объявляет переменные типа int (никогда const int):
auto a1 = i;
auto a2 = ci;
auto a3 = *pci;
auto a4 = pcs->i;
При выводе типа для параметров шаблона и автоматических переменных только высшие consts удаляются. Учитывая, что шаблон функции принимает указатель или ссылочный параметр, постоянство того, что указано или ссылка на него сохраняется:
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
Это поведение - это старые новости, применяемые как к С++ 98, так и к С++ 03. Соответствующее поведение для автоматических переменных, конечно, новый для С++ 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, это было бы невозможно.