2011-10-12 27 views
5

que tienen un conjunto de tipos relacionados con una relación uno-a-uno, por ejemplo:dos tipos en tiempo de compilación

TypeA ---> Type1 
TypeB ---> Type2 
TypeC ---> Type3 

Sé que estas relación en tiempo de compilación.

entonces, tengo una clase de plantilla que depende de estos dos tipos:

template<class T1,class T2> 
class MyClass 
{ 
    T1 foo; 
    T2 bar; 
}; 

Ahora, el usuario de la biblioteca de mi va a escribir algo como:

MyClass<TypeA,Type1> x; 

Esto es un inconveniente porque no hay una dependencia entre los dos tipos y debería ser suficiente para que el usuario especifique solo el primer tipo.

Además, la mezcla de los dos tipos no debería ser posible:

MyClass<TypeA,Type2> y; //it should not compile 

no estoy muy familiarizado con la programación meta plantilla, me dio la impresión de que esta tarea es factible, pero puedo estar equivocado.

El número de tipos involucrados es grande, sin embargo, me complace ejecutar un script para generar el código si es necesario.

¿Sabes si es posible o estoy perdiendo el tiempo? ¿Tiene alguna idea para señalarme en la dirección correcta?

Respuesta

6
template<class T> 
struct get_mapped; 

template<> 
struct get_mapped<TypeA>{ 
    typedef Type1 type; 
}; 

// and so on.... 


template<class T> 
class MyClass{ 
    typedef typename get_mapped<T>::type T2; 

    T foo; 
    T2 bar; 
}; 
3

¿Por qué no crear un tipo de envoltorio:

template <typename T1, typename T2> 
struct wrapper 
{ 
    typedef T1 type1; 
    typedef T2 type2; 
}; 

typedef wrapper<TypeA, Type1> TypeX; 
typedef wrapper<TypeB, Type2> TypeY; 
typedef wrapper<TypeC, Type3> TypeZ; 

A continuación, el usuario dice, MyClass<TypeX>;, y se definen:

template <typename T> 
class MyClass 
{ 
    typename T::type1 foo; 
    typename T::type2 bar; 
}; 

Si desea proteger contra el mal uso de la plantilla, utilice una especialización parcial:

template <typename> class MyClass; // undefined 

template <typename S, typename T> 
class MyClass<wrapper<S,T>> 
{ 
    S foo; 
    T bar; 
}; 

Este enfoque se puede ampliar fácilmente para incluir más datos de tiempo de compilación en la clase contenedora. Alternativamente, puede usar std::pair con tipos de miembro first_type y second_type en su lugar.

5
template<class T> struct TypeLetter2TypeDigit; 

template<> struct TypeLetter2TypeDigit<TypeA> { typedef Type1 type; }; 
template<> struct TypeLetter2TypeDigit<TypeB> { typedef Type2 type; }; 
template<> struct TypeLetter2TypeDigit<TypeC> { typedef Type3 type; }; 


template<class T1> // Type2 is not needed 
class MyClass 
{ 
    // Type2 is deduced. 
    typedef typename TypeLetter2TypeDigit<T1>::type T2; 
    T1 foo; 
    T2 bar; 
}; 
+0

hizo algunas correcciones. Vea si es apropiado. (Además, ¿realmente necesitas un nombre tan largo como 'TypeLetter2TypeDigit'? En mi humilde opinión, algo como 'TypeMap' es suficiente.) – iammilind

+0

@iammilind. Gracias. El nombre largo es necesario para mostrar lo que quiero. Usted u OP puede usar cualquier nombre. –

Cuestiones relacionadas