[C++] Partieele template specialisatie

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • Mijzelf
  • Registratie: September 2004
  • Niet online
Ik ben aan het proberen een c++ wrapper rond gsl vectors te schrijven. Deze bibliotheek is in C geschreven, met een groot aantal verschillende vector functies, voor verschillende basis typen, zoals allocatie functies
gsl_vector *gsl_vector_alloc( size_t n ) voor doubles, en
gsl_vector_float *gsl_vector_float_alloc( size_t n ) voor floats.

Nu probeer ik dat met partial specialized templates te wrappen:
C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
template<typename BASE> class Vector
{
public:
    class VECTOR_BASE;
    inline VECTOR_BASE *vector_alloc( size_t );
    inline vector_free( VECTOR_BASE * );
    
    Vector( size_t n )
    {
        m_pVector = vector_alloc( n );
    }
    ~Vector()
    {
        vector_free(  m_pVector );
    }
    
    VECTOR_BASE *m_pVector
};

template<> Vector<double>
{
public:
    typedef gsl_vector VECTOR_BASE;
    VECTOR_BASE *vector_alloc( size_t n ){ return gsl_vector_alloc( n ); }
    void vector_free( VECTOR_BASE *p ){ gsl_vector_free( p ); }
};

template<> Vector<float>
{
public:
    typedef gsl_vector_float VECTOR_BASE;
    VECTOR_BASE *vector_alloc( size_t n ){ return gsl_vector_float_alloc( n ); }
    void vector_free( VECTOR_BASE *p ){ gsl_vector_float_free( p ); }
};
Dit compileerd, en ik kan zo ook long double, int, ... toevoegen.

Maar de code is niet bruikbaar:
C++:
1
Vector<double> v(3);
geeft
code:
1
error C2440: 'initializing' : cannot convert from 'int' to 'Vector<double>'

C++:
1
2
Vector<double> v;
Vector<double>::VECTOR_BASE *pv = v.vector_alloc( 3 );
compileerd OK. (Niet dat ik de code zo wil gebruiken)

Het lijkt er dus op dat de gespecialiseerde templates niet de constructor van de generieke class gebruiken. Waarom niet?

Acties:
  • 0 Henk 'm!

  • Zoijar
  • Registratie: September 2001
  • Niet online

Zoijar

Because he doesn't row...

Een specialisatie is een hele nieuwe class. Die herbruikt niets. Zo hoort het te werken.

Acties:
  • 0 Henk 'm!

  • Mijzelf
  • Registratie: September 2004
  • Niet online
Echt? Hm. Dan moet ik het omdraaien, denk ik:
C++:
1
2
3
4
5
6
template<typename BASE> class GenericVector:
                  public Vector<BASE>
{
public:
          GenericVector(  size_t n );
};

[ Voor 3% gewijzigd door Mijzelf op 31-08-2012 14:40 ]


Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 03:42

.oisyn

Moderator Devschuur®

Demotivational Speaker

Dat kan, maar makkelijker is om gewoon de type-specifeke zaken buiten de class te implementeren.

C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
template<class T> struct VectorTraits;

template<> struct VectorTraits<float>
{
    typedef gsl_vector_float element_type; 
    static element_type* alloc( size_t n ){ return gsl_vector_float_alloc( n ); } 
    static void free(element_type*p){ gsl_vector_float_free( p ); } 
};

template<typename BASE> class Vector 
{ 
public:
    typedef VectorTraits<BASE> traits;
    typedef typename traits::element_type element_type; 
     
    Vector( size_t n ) 
    { 
        m_pVector = traits::alloc( n ); 
    } 
    ~Vector() 
    { 
        traits::free(m_pVector); 
    } 
     
    element_type *m_pVector; 
}; 


Overigens is "partial specialization" wat anders dan "slechts een deel specializen". Wat hier gebruikt wordt is explicit specialization - alle template arguments staan vast. Partial specialization is als je slechts specialiseert op een deel van de template argumenten.
C++:
1
2
3
4
5
6
7
template<class A, class B> struct Foo { };

// partial specialization
template<class A> struct Foo<A, int> { };

// explicit specialization
template<> struct Foo<float, int> { };

[ Voor 28% gewijzigd door .oisyn op 31-08-2012 14:59 ]

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Acties:
  • 0 Henk 'm!

  • Mijzelf
  • Registratie: September 2004
  • Niet online
OK, bedankt, dat werkt.