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

Локальные классы: С++ 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), чтобы читатели могли сравнивать себя и для справок в будущем.

4b9b3361

Ответ 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

В соответствии с моим собственным вопросом ограничение удаляется, а локальные классы могут использоваться как аргументы шаблона.
Однако я не вижу ссылки на новый стандарт.