Использование локальных классов с алгоритмами STL - PullRequest
50 голосов
/ 13 апреля 2009

Меня всегда интересовало, почему нельзя использовать локально определенные классы в качестве предикатов для алгоритмов STL.

В вопросе: Подход к алгоритмам STL, лямбда, локальные классы и другие подходы , BubbaT упоминает, что ' Поскольку стандарт C ++ запрещает использование локальных типов в качестве аргументов '

Пример кода:

int main() {
   int array[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
   std::vector<int> v( array, array+10 );

   struct even : public std::unary_function<int,bool>
   {
      bool operator()( int x ) { return !( x % 2 ); }
   };
   std::remove_if( v.begin(), v.end(), even() ); // error
}

Кто-нибудь знает, где в стандарте ограничение? В чем причина запрета локальных типов?


РЕДАКТИРОВАТЬ : Начиная с C ++ 11, в качестве аргумента шаблона допустимо использовать локальный тип.

Ответы [ 2 ]

53 голосов
/ 13 апреля 2009

Это явно запрещено стандартом C ++ 98/03.

C ++ 11 снять это ограничение.

Чтобы быть более полным:

Ограничения на типы, которые в качестве шаблона используются параметры перечислены в статье 14.3.1 C ++ 03 (и C ++ 98) стандарт:

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

template <class T> class Y { /* ... */  }; 
void func() {   
      struct S { /* ... */ }; //local class   
      Y< S > y1; // error: local type used as template-argument  
      Y< S* > y2; // error: pointer to local type used as template-argument }

Источник и более подробная информация: http://www.informit.com/guides/content.aspx?g=cplusplus&seqNum=420

Подводя итог, ограничение было ошибкой, которая была бы исправлена ​​раньше, если бы стандарт развивался быстрее ...

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

5 голосов
/ 14 апреля 2009

Ограничение будет снято в '0x, но я не думаю, что вы будете их часто использовать. И это потому, что в C ++ - 0x будут лямбды! :)

int main() {
   int array[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
   std::vector<int> v( array, array+10 );

   std::remove_if( v.begin()
                 , v.end()
                 , [] (int x) -> bool { return !(x%2); })
}

Мой синтаксис в вышеприведенном может быть не идеальным, но общая идея есть.

...