Как стандарт C ++ 0x определяет множественные объявления C ++ Auto? - PullRequest
2 голосов
/ 30 января 2009

ммм, у меня есть небольшая путаница в отношении нескольких автоматических объявлений в грядущем стандарте C ++ 0x.

auto a = 10, b = 3.f , * c = new Class();

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

Возможен перевод 1:

int a = 10; 
int b = 3.f; 
int * c = new Class ();

вызывает ошибку

Возможен перевод 2:

int a = 10;
float b = 3.f;
Class * c = new Class (); 

как приведено в стандарте?

Если я могу сказать, что мой POV, перевод №2 был самым интересным, по крайней мере, для меня, что я обычный пользователь C ++. Я имею в виду, что для меня "каждая объявленная переменная имеет тот же объявленный тип", ведьма - это auto. Перевод № 1 был бы действительно не интуитивным для меня.

До свидания QbProg

Ответы [ 4 ]

6 голосов
/ 30 января 2009

Вероятно, это не последняя версия, но мой черновой стандарт C ++ 0x от июня 2008 г. говорит, что вы можете делать следующее:

auto x = 5; // OK: x has type int
const auto *v = &x, u = 6; // OK: v has type const int*, u has type const int

Так что, если что-то не изменилось с июня, это (или будет) разрешено в ограниченной форме с довольно интуитивным толкованием.

Ограничение состоит в том, что если вы хотите выстроить несколько автоматических объявлений, как это (используя пример выше), это работает, потому что выведенный тип v и u имеет один и тот же «базовый тип» (int в этом case) использовать неточный термин.

Если вам нужно точное правило, проект стандарта гласит:

Если список деклараторов содержит более одного декларатора, тип каждой объявленной переменной определяется как описано выше. Если тип, выведенный для параметра шаблона U, не одинаков при каждом вычете, программа некорректна.

где "выводимый параметр шаблона U" определяется по:

выведенный тип параметра u в вызове f (expr) следующего изобретенного шаблона функции:

 `template <class U> void f(const U& u);`

Почему они придумали это правило вместо того, чтобы сказать что-то вроде:

auto a = 10, b = 3.f , * c = new Class();

эквивалентно:

auto a = 10;
auto b = 3.f;
auto * c = new Class();

Я не знаю. Но я не пишу компиляторы. Вероятно, что-то связанное с тем, что вы выяснили, что ключевое слово auto заменяет, вы не можете изменить его в том же выражении.

Взять например:

int x = 5;
CFoo * c = new CFoo();

auto  a1 = x,       b1 = c; // why should this be permitted if
int   a2 = x, CFoo* b2 = c; // this is not?

В любом случае, я в любом случае не люблю помещать несколько объявлений в одно и то же утверждение.

4 голосов
/ 30 января 2009

Раздел 7.1.6.4 чернового стандарта подразумевает, что вы не можете смешивать типы, как в возможном переводе 2. Поэтому ни один из возможных переводов не является действительным.

2 голосов
/ 30 января 2009

Есть несколько моментов, которые, я думаю, помогут внести вклад в текущую формулировку. Первое - это последовательность. Если вы напишите декларацию, такую ​​как:

int j;
int i = 0, *k = &j;

Затем оба типа используют int где-то в своем типе. Это ошибка, например, если j был const int. То, что auto работает так же, "соответствует" текущей модели для таких объявлений.

В этом случае есть практическое преимущество с точки зрения автора компилятора. В компиляторах уже существует механизм, позволяющий выполнять вывод типа для вызова функции (именно так auto описывается как работающий). Приведенное выше правило согласуется с правилом, согласно которому вычет для параметра шаблона должен иметь такой же тип:

template <typename T> void foo (T, T*);

void bar ()
{
  int i;
  const int j = 0;

  foo (i, &i);  // OK deduction succeeds T == int
  foo (i, &j);  // ERROR deduction fails T == int or const int.
}

Простая реализация для auto состоит в том, чтобы повторно использовать существующую механику для определения типа для auto , и из-за согласованности с текущим поведением результат не будет слишком удивительным для людей. .

Наконец, и это, пожалуй, самый важный момент на мой взгляд. Текущая модель является консервативной и работает очень похоже на существующие языковые конструкции в C ++. Поэтому шансы на то, что это приведет к ошибке языка, препятствующей показу, очень малы. Однако текущая модель может быть легко расширена в будущем, чтобы содержать другие примеры, перечисленные в вашем вопросе.

Более того, это расширение не нарушит код, который использует текущую формулировку auto . Подумайте, сделали ли они это наоборот. Если расширенная версия auto была первой версией, и это привело к некоторому странному и фатальному недостатку с ключевым словом, то это потребовало бы удаления языковой функции из стандарта - чего-то, что почти никогда не происходит, как это скорее всего нарушает код.

0 голосов
/ 30 января 2009

Первый тип будет соответствовать тому, как работает вывод типа в типе возврата оператора?:.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...