Использование auto в С++ 11
Когда я использую auto
для вывода типа указателя, я обнаружил странное явление. Мой код выглядит следующим образом:
#include <iostream>
using namespace std;
int main()
{
int i = 100;
auto p1 = &i;
auto *p2 = &i;
cout << *p1 << " " << *p2 << endl;
return 0;
}
После компиляции и выполнения мы можем обнаружить, что результат *p1
и *p2
одинаковый, оба 100. Это означает, что p1
и p2
являются объектами-указателями, которые указывают на int
объект.
[[email protected] ~]$ ./test
100 100
Есть ли разница между этими двумя утверждениями, которые определяют p1
и p2
?
Ответы
Ответ 1
Разница заключается в том, что в первом случае auto выводится на int*
, а во втором случае auto выводится на int
, что приводит к типу p1
и p2
типа int*
.
Механизм вычитания типа для авто эквивалентен механизму аргументов шаблона. Таким образом, вывод типа в вашем примере аналогичен
template<typename T>
void foo(T p1);
template<typename T>
void bar(T* p2);
int main()
{
int i;
foo(&i);
bar(&i);
}
где обе функции создаются как тип void (int *), но в первом случае T
выводится на int*
, а во втором случае T
имеет тип int
.
Ответ 2
auto
спецификатор, используемый в объявлениях переменных, выводит его тип с теми же правилами, что и в аргументе template вычет.
Рассмотрим ваш первый пример (т.е. auto p1 = &i;
). Тип Спецификатор auto
выводится следующим образом:
-
auto
заменяется параметром шаблона воображаемого типа (например, U p1 = &i;
).
-
&i
type int*
, поэтому без сюрпризов и согласно правилам вычитания шаблона U
выводится int*
.
Теперь рассмотрим ваш второй пример (т.е. auto *p2 = &i
).
- Опять
auto
заменяется параметром шаблона воображаемого типа (например, U* p1 = &i;
).
-
&i
type int*
, поэтому согласно правилам вычитания шаблона U
выводится int
.
Таким образом, в auto *p2 = &i;
тип заполнителя auto
будет корректно выведен как int
, а не как int*
, что приведет к тому, что p2
будет иметь тип int**
, как вы могли ожидать.