Подтвердить что ты не робот

Использование 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?

4b9b3361

Ответ 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**, как вы могли ожидать.