2011-07-25 15 views
9

que tienen una plantilla de clase similar a la que sigue a continuación que está diseñado para incluir algunos valores de configuración utilizados al analizar archivos CSV:soportes Evitar de plantilla de clase Tener Parámetro

template <typename InputIterator = default_all> 
class icsv_params 
{ 
    // Iterator to a data structure containing the columns 
    // that should be read. 
    typedef InputIterator iterator; 
    // This is a bitmask type. 
    typedef detail::icsv_op icsv_op; 

    static const icsv_op noqt = icsv_op(detail::csv_flags::noqt); 
    static const icsv_op quot = icsv_op(detail::csv_flags::quot); 
    static const icsv_op mmap = icsv_op(detail::csv_flags::mmap); 

    // The rest of the class definition isn't relevant. 
}; 

Ahora, el parámetro de plantilla es importante cuando el usuario desea suministrar iteradores de inicio y final a una estructura de datos que contiene los números de las columnas que deben analizarse; sin embargo, si el usuario no proporcionara los iteradores como parámetros, la clase debería asumir automáticamente que todas las columnas deben ser analizadas.

En el segundo caso, el código para declarar una instancia de la clase parece difícil de manejar:

icsv_params<> params(...); 

Además, los tipos de máscara de bits noqt, quot y mmap son utilizados por solamente esta clase, así que tiene sentido ponerlos dentro de la definición de la clase; Sin embargo, si el usuario desea utilizar estas máscaras de bits tipos, el código para hacerlo también es difícil de manejar:

icsv_params<> params(icsv_params<>::noqt); 

¿Cómo puedo hacerlo de modo que el usuario no necesita proporcionar los soportes angulares para indicar la ausencia de un parámetro de plantilla? Si no hay manera de hacerlo, ¿qué alternativa sugerirías?

+1

de función no necesitan los soportes. Asumiendo C++ 0x, el código de usuario puede hacer 'auto params = some_factory_function (...);'. –

Respuesta

4

Lamentablemente, esta es la sintaxis de C++. IIRC, en C++ 0x, hay espacios de nombres asociados (que resuelven su segunda pregunta).

Para el primero, un typedef debe hacer, a la STL: Plantillas

template <typename InputIterator = default_all> 
class basic_icsv_params 
{ 
    ... 
}; 

typedef basic_icsv_params<> icsv_params: 
+0

¡Gracias por la respuesta! Esto todavía deja una sensación insatisfecha en mi estómago ya que el usuario tendrá que escribir el prefijo 'basic_' cuando proporcione el parámetro de la plantilla. Hasta ahora, solo GCC e IMB C++ admiten esta función = (. Afortunadamente esta característica se implementa rápidamente en otros compiladores. –

+1

@ void-pointer: así es como funciona la biblioteca estándar. De hecho, 'std :: string' es un typedef para 'std :: basic_string , Allocator = std :: allocator >'. –

0

Normalmente para los parámetros del iterador, el tipo de iterador es un parámetro de plantilla solo para las funciones que los necesitan. Por ejemplo, si observas el constructor std::vector, está modelado con los iteradores begin() y end(), pero no el tipo completo.

+0

La clase de OP podría ser algún tipo de clase de rasgos y, por lo tanto, realmente podría necesitar el tipo de iterador como parámetro de plantilla. –

+0

Pensé en hacer eso, pero aquí es donde el resto de la definición de clase se vuelve relevante: si el usuario proporciona los tipos de iterador, entonces la clase necesitará almacenar instancias de ese tipo de iterador para que el método que es responsable de analizar el El archivo CSV puede recuperarlos más tarde. ¿Puedo cumplir esta limitación? –

0

Poner llaves angulares en mi opinión es una mejor manera de hecho. Dado que, no pueden ser ingonados, la manera alternativa puede ser,

typedef icsv_params<> icsv_params_default; 
Cuestiones relacionadas