Локальные классы: С++ 03 против С++ 11
Есть ли какие-либо изменения в использовании локального класса в С++ 11?
Кажется, что в С++ 03 локальные классы не могут использоваться в качестве аргумента шаблона (напомню это).
Рассмотрим этот код,
template<typename T> void f(const T&) {}
//Note : S is a local class defined inside main()
int main() { struct S{}; f(S()); } //I want template argument to be deduced.
Но он дает ошибку компиляции (режим С++ 03), говоря (ideone):
prog.cpp: 4: ошибка: нет соответствующей функции для вызова на 'f (main():: S)
Однако он компилируется при компиляции в режиме С++ 11 (ideone), что имеет смысл для меня, иначе лямбда не сработает. Поэтому я предполагаю, что по крайней мере это изменение в использовании локальных классов. Я прав? Каковы другие изменения в отношении локальных классов?
Пожалуйста, укажите соответствующий текст из Стандартов (С++ 03 и С++ 11), чтобы читатели могли сравнивать себя и для справок в будущем.
Ответы
Ответ 1
Различия видны путем сравнения §14.3.1/2 в обоих стандартах.
-
С++ 03
Локальный тип, тип без привязки, неназванный тип или тип, составленный из любого из этих типов, должен не используется в качестве шаблона-аргумента для параметра типа шаблона. [Пример:
template <class T> class X { /* ... */ };
void f()
{
struct S { /* ... */ };
X<S> x3; // error: local type used as template-argument
X<S*> x4; // error: pointer to local type used as template-argument
}
-end example] [Примечание: аргумент типа шаблона может быть неполным (3.9). ]
-
С++ 0x (n3290)
[Пример:
template <class T> class X { };
template <class T> void f(T t) { }
struct { } unnamed_obj;
void f() {
struct A { };
enum { e1 };
typedef struct { } B;
B b;
X<A> x1; // OK
X<A*> x2; // OK
X<B> x3; // OK
f(e1); // OK
f(unnamed_obj); // OK
f(b); // OK
}
- конец примера] [Примечание. Аргумент типа шаблона может быть неполным (3.9). - конечная нота]
С++ 03 явно запрещает локальные классы в аргументах типа шаблона. С++ 11 не содержит и даже включает пример допустимого использования таких.
Ответ 2
Из более старого стандарта:
(14.3) Локальный тип, тип без привязки, неназванный тип или тип, смешанный с любым из этих типов, не должны использоваться в качестве аргумента шаблона для параметра типа шаблона.
Кажется, что он удален в стандарте С++ 11.
Дополнительные ограничения:
(9.8) Объявления в локальном классе могут использовать только имена типов, статические переменные, внешние переменные и функции, а также перечисления из охватывающих объем.
(9.8) Локальный класс не должен иметь шаблонов членов.
(14.5.4) Шаблон друга не должен быть объявлен в локальном классе.
(9.4.2) Локальный класс не должен содержать статических данных.
(9.3) Функции-члены локального класса (9.8) не имеют связи.
Ответ 3
В соответствии с моим собственным вопросом ограничение удаляется, а локальные классы могут использоваться как аргументы шаблона.
Однако я не вижу ссылки на новый стандарт.