Как стандарт C ++ 0x определяет C ++ Auto multiple объявления?
Вопрос
ммм, у меня просто небольшая путаница с несколькими автоматическими объявлениями в предстоящем стандарте 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 ();
как это приведено в стандарте?
Если я могу высказать свое мнение, перевод № 2 был самым обнадеживающим, по крайней мере, для меня, поскольку я обычный пользователь C ++ .Я имею в виду, для меня "каждая объявленная переменная имеет один и тот же объявленный тип", witch - это auto .Перевод № 1 был бы для меня действительно неинтуитивным.
До свидания QbProg
Решение
Вероятно, это не последняя версия, но в моем проекте стандарта 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), чтобы использовать неточный термин.
Если вам нужно точное правило, в проекте стандарта сказано следующее:
Если список деклараторов содержит более одного декларатора, тип каждой объявленной переменной определяется, как описано выше.Если тип, выведенный для параметра шаблона 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?
В любом случае, я все равно не сторонник помещать несколько объявлений в одно и то же утверждение.
Другие советы
В проект стандарта раздел 7.1.6.4 подразумевает, что вы не можете смешивать типы, как в possible translation 2.Таким образом, ни один из возможных переводов не является действительным.
Есть несколько моментов, которые, я думаю, помогут внести свой вклад в нынешнюю формулировку.Первое - это последовательность.Если вы напишете декларацию, такую как:
int j;
int i = 0, *k = &j;
Затем оба этих типа используют инт где-то в их вкусе.Это ошибка, например, если 'j' было 'const int'.Имея авто работа же "согласуется" с текущей моделью для таких объявлений.
Тогда возникает практическое преимущество с точки зрения автора компилятора.В компиляторах уже существует механизм для выполнения вывода типа для вызова функции (который заключается в том, как авто описывается как работающий).Приведенное выше правило согласуется с правилом , согласно которому вычет для параметра шаблона должен приводить к тому же типу:
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.
}
Простая реализация для авто заключается в повторном использовании существующей механики для определения типа для авто, и из-за соответствия текущему поведению результат не будет слишком неожиданным для людей.
Наконец, и это, наверное, самый важный момент, на мой взгляд.Текущая модель консервативна и работает очень похоже на существующие языковые конструкции в C ++.Поэтому вероятность того, что это приведет к языковой ошибке, останавливающей показ, очень мала.Однако текущая модель может быть легко расширена в будущем, чтобы содержать другие примеры, которые вы перечисляете в своем вопросе.
Более того, это расширение не приведет к нарушению кода, использующего текущую формулировку авто.Подумайте, сделали ли они это наоборот.Если расширенная версия авто это была первая версия, и это привело к некоторому странному и фатальному недостатку с ключевым словом, тогда потребовалось бы удаление языковой функции из стандарта - чего почти никогда не происходит, поскольку это, скорее всего, нарушает код.
Первый из них как бы соответствовал бы тому , как работает вывод типа в возвращаемом типе ?:оператор.