2010-03-29 5 views
4

Imaginez que j'ai une fonction de modèle comme celui-ci:C++ - typedef "inside" arguments de modèle?

template<typename Iterator> 
void myfunc(Iterator a, typename Iterator::value_type b) 
{ ... } 

est-il un moyen de mettre en œuvre la même chose en déclarer un typedef pour Iterator :: valuetype que je peux utiliser dans la signature de la fonction? Par exemple, je préfère être en mesure de faire quelque chose comme ceci:

template< 
    typename Iterator, 
    typedef Iterator::value_type type> 
void myfunc(Iterator a, type b) 
{ ... } 

Jusqu'à présent, j'ai eu recours à l'aide d'arguments de modèle par défaut et Boost concept de vérification pour assurer la valeur par défaut est toujours utilisé:

template< 
    typename Iterator, 
    typename type = typename Iterator::value_type > 
void myfunc(Iterator a, type b) 
{ 
    BOOST_STATIC_ASSERT((
     boost::is_same< 
      typename Iterator::value_type, 
      type 
     >::value 
    )); 
    ... 
} 

... mais ce serait bien s'il y avait un support dans la langue pour ce genre de chose.

Modifier

Je devrais probablement avoir utilisé une classe au lieu d'une fonction, étant donné que les arguments par défaut ne sont pas standard pour les fonctions.

template< 
    typename T, 
    typename V = typename T::value_type> 
class A : public B<T, V> 
{ 
    BOOST_STATIC_ASSERT((boost::is_same<typename T::value_Type, V>::type)); 
}; 
+0

Remarque: les arguments de modèle par défaut sur les modèles de fonction sont une extension. Ils ne sont pas en C++ 03. –

+0

J'ai également réparé votre autre lieu d'omission de type. J'espère que cela ne vous dérange pas. –

Répondre

2

Vous cherchez un typedef à utiliser basé sur un modèle dans une définition de fonction basé sur un modèle. Je ne pense pas que vous pouvez faire ...

Vous pouvez avoir une classe avec une fonction basé sur un modèle statique & de typedefs ... Mais son utilisation devient laid:

template<typename Iterator> 
class arbitraryname 
{ 
public: 
    typedef typename Iterator::value_type value; 

    static void myfunc(Iterator a, value b) 
    { 
    value c = b; 
    cout << "Test" << c << endl;  
    } 
}; 

struct Foo 
{ 
    typedef int value_type; 
}; 

int main() 
{ 
    Foo f; 
    myfunc<Foo>(f,2); // Old way. 
    arbitraryname<Foo>::myfunc(f,3); // With templated class. 
} 

Personnellement, dans ce cas, Je vais avec un #define ...

#define VALUE_TYPE typename Iterator::value_type 
template<typename Iterator> 
void myfunc(Iterator a, VALUE_TYPE b) 
#undef VALUE_TYPE 
{ 
    typedef typename Iterator::value_type bar; 
    bar z = b; 
    cout << "Test" << z << endl; 
} 

Bien sûr #define « s sont laids et pécheurs. Mais le code est douloureusement obtus à lire ...

p.s. Pour être sûr, vous pouvez ajouter:

#ifdef VALUE_TYPE 
#error "VALUE_TYPE already defined!" 
#endif 
2

Vous pouvez utiliser typename dans la liste des paramètres:

template <typename Iterator> 
void myfunc(Iterator a, typename Iterator::value_type b) 
{ 
} 
+0

Oh, le nom de fichier manquant est un bug dans mon exemple, merci d'avoir attrapé ça. Cependant, ce n'est pas la question à laquelle j'essaie de répondre. Ce que j'aimerais vraiment, c'est rendre la signature de la fonction moins verbeuse en utilisant un typedef pour b. –

+0

@redmoskito: Je ne suis pas sûr de comprendre ce que vous cherchez à accomplir. Votre deuxième extrait de code est plus long que le premier, et le troisième est relativement gigantesque. En regardant uniquement la verbosité, la première est la meilleure option. Au meilleur de ma connaissance, c'est aussi votre seule option. Il n'y a aucun moyen d'accomplir ce que vous montrez dans le deuxième extrait et le troisième extrait, bien qu'autorisable en C++ 0x, n'est pas valide en C++ 03 (seul le modèle de classe peut avoir des arguments de modèle par défaut en C++ 03). –

+0

vous pourriez finir par faire moins verbeux mais IMO se débarrasser du type explicite pour votre itérateur de la signature de la fonction le rendra moins clair à moins que vous choisissiez quelque chose de mieux libellé que 'type' – hhafez