Uso de clases locales con algoritmos STL


Siempre me he preguntado por qué no se pueden usar clases definidas localmente como predicados para algoritmos STL.

En la pregunta: Aproximándose a algoritmos STL, lambda, clases locales y otros acercamientos, BubbaT mentions dice que ' Dado que el estándar de C++ prohíbe usar tipos locales como argumentos '

Código de ejemplo:

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
}

¿Alguien sabe en qué parte del estándar está la restricción? ¿Cuál es la razón para no permitir locales tipos?


EDIT : Desde C++11, es legal usar un tipo local como argumento de plantilla.

Author: Community, 2009-04-13

2 answers

Está explícitamente prohibido por el estándar C++98/03.

C++11 elimina esa restricción.

Para ser más completo:

Las restricciones en los tipos que son los parámetros utilizados como plantilla se enumeran en el artículo 14.3.1 del C++03 (y C++98) estándar:

Un tipo local, un tipo sin vinculación, un tipo sin nombre o un tipo compuesto de cualquiera de estos tipos no será utilizado como argumento de plantilla para un plantilla tipo-parámetro.

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 }

Fuente y más detalles: http://www.informit.com/guides/content.aspx?g=cplusplus&seqNum=420

En resumen, la restricción fue un error que se habría solucionado antes si el estándar evolucionara más rápido...

Dicho esto hoy en día, la mayoría de las últimas versiones de compiladores comunes lo permiten, junto con proporcionar expresiones lambda.

 52
Author: Klaim,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-02-02 12:52:35

La restricción se eliminará en '0x, pero no creo que las uses mucho. Y eso es porque C++-0x va a tener lambdas! :)

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); })
}

Mi sintaxis en lo anterior puede no ser perfecta, pero la idea general está ahí.

 5
Author: Richard Corden,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-04-14 10:46:46