2010-08-10 8 views
2

Je ne suis pas sûr si le titre a un sens.C++ modèle argument référence/valeur trait

laissez-moi vous expliquer ce que je veux faire:

Je constructeur de modèle, l'argument doit généralement référence, mais peut être la valeur dans certains cas. En fin de compte, je voudrais avoir quelque chose comme:

matrix_adapter(typename adaptable<T,A>::type); 

adaptable<T,A>::type peut être soit la valeur ou référence défendais le type de A. Je ne suis pas en mesure de le faire (modèle instanciation ne se produit pas), et incertain Pourquoi.

En ce moment, ma solution est d'activer/désactiver l'utilisation constructeur Sfinae:

matrix_adapter(A a, typename adaptable<T,A>::pass_by_value = 0) 

cependant, qui nécessite deux constructeurs qui sont essentiellement les mêmes. Est-il possible de le faire en utilisant un constructeur générique?

Est-il possible de le faire en utilisant un constructeur générique?

plus de code:

template<typename T> 
struct adaptable<T, boost::detail::multi_array::const_sub_array<T, 2, const T*> > 
{ 
    typedef void* pass_by_value; 
    typedef boost::detail::multi_array::const_sub_array<T, 2, const T*> type; 
    static size_t size1(const type &A) { return A.shape()[0]; } 
    static size_t size2(const type &A) { return A.shape()[1]; } 
    static const T* data(const type &A) { return A.origin(); } 
}; 

template<typename T, class L = ublas::column_major> 
struct matrix_adapter 
    : ublas::matrix<T, L, ublas::array_adaptor<T> > 
{ 
    typedef ublas::array_adaptor<T> array_type; 
    typedef ublas::matrix<T, L, array_type> base; 
    matrix_adapter(size_t size1, size_t size2, T *data) 
     : base(size1, size2, array_type(size1*size2, pointer())) 
    { 
     initialize(data); 
    } 

    template<class A> 
    matrix_adapter(A a, typename adaptable<T,A>::pass_by_value = 0) 
     : base(adaptable<T,A>::size1(a), 
       adaptable<T,A>::size2(a), 
       array_type(adaptable<T,A>::size1(a)* 
          adaptable<T,A>::size2(a), 
          pointer())) 
    { 
     initialize(adaptable<T,A>::data(a)); 
    } 

    template<class A> 
    matrix_adapter(A &a) 
     : base(adaptable<T,A>::size1(a), 
       adaptable<T,A>::size2(a), 
       array_type(adaptable<T,A>::size1(a)* 
          adaptable<T,A>::size2(a), 
          pointer())) 
    { 
     initialize(adaptable<T,A>::data(a)); 
    } 
+0

Quelle est votre définition de 'adaptable'? Et la raison pour laquelle le premier ne fonctionnera pas est que ':: type' est * dépendant * de' T', donc il n'y a rien à déduire avec 'T'. – GManNickG

+0

@GMan @wil plus de code posté – Anycorn

+0

Je ne sais pas ublas. Va utiliser 'template matrice_adapter (A const & a): ...' ne fonctionne pas pour un paramètre? – wilx

Répondre

1

Votre constructeur lui-même est un modèle, mais avec une signature de matrix_adapter(typename adaptable<T,A>::type) le compilateur ne peut pas déduire le type de A de l'appel. En utilisant SFINAE vous autorisez le compilateur à déduire A du premier argument constructeur, puis le second argument empêche l'un ou l'autre d'être pris en compte dans l'ensemble de surcharge.

Je ne crois pas qu'il soit possible d'éliminer l'un ou l'autre des constructeurs.

Questions connexes