Точка объявления для ключевого слова auto - программирование
Подтвердить что ты не робот

Точка объявления для ключевого слова auto

У меня был Q & A до: Точка декларации в С++. Правило-точка-декларация хорошо применима во многих ситуациях. Теперь я смутил использование auto в сочетании с этим правилом.

Рассмотрим эти два кода:

я. Объявление x само по себе (мы не ожидаем его работы):

{
  auto x = x;
}

II. Объявление внутреннего x внешним x (оно делает ошибку в gcc 4.8.x):

{
  int x = 101; // the outer x
  {
    auto x = x; // the inner x
  }
}

Согласно правилу пункта декларации, он должен работать, но это не так. Кажется, в стандарте есть еще одно правило, которое я пропустил. Вопрос в том, что Где точка объявления при использовании auto?

 

Есть две возможности:

я. Если точка объявления после =, в конце инструкции:

auto object = expression;
                        ^
                        Is it here? If it is, why gcc complains?

Таким образом, второе объявление является действительным и должно работать, потому что нет x, а внешнего (что объявлено ранее). Поэтому auto x=x допустим, а внутренний x должен быть назначен 101.

 

II. Если точка объявления находится перед =:

auto object = expression;
           ^

Ну, это не имеет никакого смысла, потому что auto должен ждать, пока не увидит следующее выражение. Например, auto x; недействителен.


Обновить. Мне нужен ответ, который объясняет это точкой правила объявления.

4b9b3361

Ответ 1

auto x = x; // inner x

плохо сформировался.

Чтобы привести цитату из стандарта С++ 11 (выделение мое):

7.1.6.4 авто-спецификатор

...

3 В противном случае тип переменной выводится из ее инициализатора. Имя объявляемой переменной не будет отображаться в выражении инициализатора....

Итак, поскольку x после = разрешается x в auto x (как объяснялось в связанном вами вопросе), это выше фрагмент кода плохо сформирован.

Ответ 2

Как и в любом другом определении, x в правой части инициализатора для auto x = x разрешается локальному auto x. С++ всегда делал это (т.е. int x = x компилирует, но дает вам поведение undefined).

Причина auto x = x не удается скомпилировать, потому что пока x находится в области видимости, он еще не имеет известного типа и поэтому использует его как инициализатор, потому что тип не может быть выведен из выражения.

Как и любой другой вид объявления, x находится в области видимости после своего объявления, которое auto x.

int x = 10;
int y = 20;
{
    int x = x;  // This is NOT the outer x. This is undefined behaviour (reading an
                // uninitialised variable).
    auto y = y; // This is NOT the outer y. This is a compile error because the type of
                // y is not known.
}

Ответ 3

Просто добавьте пример с более явной диагностикой:

auto ll = [&] { ll(); };

Результаты в (gcc):

error: variable ‘auto ll’ with ‘auto’ type used in its own initializer

или (clang):

error: variable 'll' declared with 'auto' type cannot appear in its own initializer
    auto ll = [&] { ll(); };
                    ^

Вы можете видеть, что для этого существует явное правило. Я не смотрел спецификации.

Ответ 4

Компилятор читает целое утверждение (от начала строки до следующей полутопликации), а затем оценивает различные части оператора с использованием приоритетов операций, а затем, когда приходит время, когда значение auto x должен быть присвоен тип, который появился после того, как принят знак =.

Например:

template <typename T>
T sum(T a, T b)
{
    return a+b;
}

int main()
{
    auto x = sum<double>(1,5); // x here is a double, because the return value is double
    auto y = sum<int>(1,7); //y is an int, because the return value is int
}

И о вашем auto x = x, вы переопределяете одно и то же имя переменной. Это недействительно! auto y = x будет работать.