2013-01-14 1 views
0

Dire que j'ai une fonction de modèle qui accepte des arguments variables et appelle d'autres fonctions avec ces arguments ...Le passage des arguments variables dans un template C++ variadique

template<typename... A> func(int i, A... args) 
{ 
    // do something common 

    switch (i) 
    { 
    case 0: x(args...); break; 
    case 1: y(args...); break; 
    case 2: z(args...); break; 

    default: break; 
    } 

    // do something common 
} 

... et les autres fonctions sont définies comme .. .

void x(int a, int b); 
void y(int a, int b); // note: takes same args as x() 
void z(std::string a); 

Cela ne compile pas parce que l'appel func() avec un std :: argument de chaîne ne sera pas trouver une correspondance pour x() et y() qui prend un std :: argument de chaîne.

Notez que func() utilise des critères externes (la valeur du paramètre i dans cet exemple) pour décider à quelle autre fonction transmettre les arguments de paramètre.

Existe-t-il un moyen de retirer ceci sans avoir recours à quelque chose comme bourrer des arguments de paramètre dans un std: tuple et passer cela?

[EDIT]

Ok, je me suis dit une approche qui fonctionne assez bien pour mes besoins. Voici un exemple de classe pour illustrer ...

class X 
{ 
    private: 

    bool a(int) { return true; } 
    bool b(int) { return true; } 

    template<typename... A> bool a(const A&...) { return false; } 
    template<typename... A> bool b(const A&...) { return false; } 

    public: 

    template<typename... A> void x(int i, const A&... args) 
    { 
     if (i == 0) 
     { 
      a(args...); 
     } 
     else 
     { 
      b(args...); 
     } 
    } 
}; 

Les méthodes de modèle variadique pour un() et b() attrapera les appels à x.x() où les arguments ne sont pas un seul int. Cela résout l'erreur de compilation que je recevais et active l'API de classe plus simple que je recherchais.

+1

Vous devrez utiliser la spécialisation/SFINAE. –

Répondre

2

Oui, faire des surcharges distinctes:

template <typename A1> 
func(A1 arg1) 
{ 
    x(arg1); 
} 

template <typename A1, typename A2> 
func(A1 arg1, A2 arg2) 
{ 
    y(arg1, arg2); 
} 

template <typename A1, typename A2, typename A3> 
func(A1 arg1, A2 arg2, A3 arg3) 
{ 
    z(arg1, arg2, arg3); 
} 

(. Tout supplémentaire, code commun peut bien sûr être pris en compte dans une fonction distincte, commune, peut-être un modèle de fonction variadique)

+0

Pas tout à fait ce que je cherchais, mais c'est de ma faute si je ne fournis pas assez d'informations. func() peut appeler d'autres méthodes qui prennent les mêmes types d'arguments (par exemple, a (int) et b (int)), mais décide lequel appeler en fonction d'autres critères (par exemple, la valeur de i). Je vais modifier la question pour éclaircir cela. – user1715664

+0

Le cas d'utilisation que je possède est un automate où un type d'événement et ses données sont transmis. En fonction de l'état actuel et du type d'événement, le gestionnaire d'événements approprié est appelé pour traiter les données. – user1715664

+0

@ user1715664: Cela ressemble beaucoup plus à un problème * dynamique *, pas à un problème statique. –

0

un coup d'oeil à ce poste, je sais que vous pouvez utiliser ... comme un paramètre pour dire que vous utilisez un nombre variable de paramètres.

... syntax in C++

Ceci est un autre exemple avec le code bien commenté: Functions with Variable Argument Lists in C and C++ using va_list

J'espère que cela aide.

+1

Argh. S'il vous plaît, ne postez pas 'va_list' sur des questions C++ * jamais *. –

+1

@BartekBanachewicz Pourriez-vous expliquer quelles sont vos préoccupations? –

+0

@ user1715664 Que pensez-vous de la solution que j'ai posté ci-dessus? –

Questions connexes