Локальные классы: C ++ 03 против C ++ 11 - PullRequest
21 голосов
/ 20 ноября 2011

Есть ли какие-либо изменения в использовании локального класса в C ++ 11?

Кажется, в C ++ 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.

Но он выдает ошибку компиляции (режим C ++ 03), говоря ( ideone ):

прог.cpp: 4: ошибка: нет соответствующей функции для вызова 'f (main () :: S)'

Однако, он компилируется нормально при компиляции в режиме C ++ 11 (ideone ), что имеет смысл для меня, иначе лямбда не сработает.Поэтому я предполагаю, что по крайней мере это изменение в использовании локальных классов.Я прав?Какие другие изменения касаются локальных классов?

Пожалуйста, процитируйте соответствующий текст из Стандартов (C ++ 03 и C ++ 11 оба), чтобы читатели могли сравнить себя и для дальнейшего использования.

Ответы [ 3 ]

12 голосов
/ 20 ноября 2011

Различия видны при сравнении §14.3.1 / 2 в обоих стандартах.

  • C ++ 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
    }
    

    - конец примера] [Примечание: аргумент типа шаблона может быть неполного типа (3.9). ]

  • C ++ 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). - конец примечания]

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

10 голосов
/ 20 ноября 2011

Из более старого стандарта:

(14.3) Локальный тип, тип без связи, безымянный тип или тип, составленный из любого из этих типов, не должны использоваться в качестве аргумента шаблонадля параметра типа шаблона.

Кажется, он удален в стандарте C ++ 11.

Дополнительные ограничения:

(9,8)Объявления в локальном классе могут использовать только имена типов, статические переменные, внешние переменные и функции и перечислители из окружающей области.

(9.8) Локальный класс не должен иметь шаблонов членов.

(14.5.4) Шаблон друга не должен быть объявлен в локальном классе.

(9.4.2) Локальный класс не должен иметь статических членов-данных.

(9.3) Функции-члены локального класса (9.8) не имеют связи.

2 голосов
/ 20 ноября 2011

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

...