2017-02-20 1 views
0

J'ai une fonction variadique qui appelle une fonction pour chaque argument.Existe-t-il un moyen de passer le vide comme argument?

Voici ce qu'il ressemble à:

void Call() 
{ 

} 

template<typename T> 
void Call(T arg) 
{ 
    PushArg(arg); 
    Call(); 
} 

template<typename T, typename ...Args> 
void Call(T arg, Args... args) 
{ 
    PushArg(arg); 
    Call(std::forward<Args...>(args)...); 
} 

template<typename T> 
void PushArg(T arg) 
{ 

} 

template<> 
void PushArg<int>(int arg) 
{ 

} 

Si j'appelle la fonction avec Call(2, 2) il appellera PushArg<int>(2) deux fois, puis appelez Call(). Mais je dois être en mesure d'appeler PushArg mais sans valeur.

Ce que je veux être en mesure de faire est de faire Call(2, void, 4) et l'ont appelé PushArg<int>(2), PushArg<void>(), puis PushArg<int>(4).

Pour l'instant j'ai une classe "null" qui n'existe que pour me permettre de passer une valeur sans valeur, mais cela rend l'appel de la fonction maladroit. Fait ce que j'ai décrit (ou quelque chose de similaire) possible? Non, vous ne pouvez pas passer un type comme argument d'une fonction.

+0

Non, vous ne pouvez pas C++ 'void' remplir ce rôle. Vous devez utiliser un espace réservé. –

+0

Où est défini 'arg', utilisé dans la fonction' Call' variadique? –

+0

@ Cheersandhth.-Alf Pouvez-vous expliquer ce que vous demandez? J'ai dû modifier fortement le code original pour le rendre petit et lisible donc il est possible que j'ai accidentellement omis quelque chose d'important. – user112513312

Répondre

2

La seule solution que je peux penser est un type spécial (votre "classe nulle", je suppose) pour remplacer void.

Je pense que c'est une solution propre, je propose donc un exemple

#include <utility> 
#include <iostream> 

struct voidWrp 
{ }; 

void PushArg() 
{ std::cout << "- void PushArg" << std::endl; } 

template <typename T> 
void PushArg (T arg) 
{ std::cout << "- generic (T) PushArg" << std::endl; } 

template <> 
void PushArg<int> (int arg) 
{ std::cout << "- int PushArg" << std::endl; } 

void Call() 
{ } 

template <typename T> 
void Call (T arg) 
{ 
    PushArg(arg); 
    Call(); 
} 

template <typename T, typename ... Args> 
void Call (T arg, Args ... args) 
{ 
    PushArg(arg); 
    Call(std::forward<Args>(args)...); 
} 

template <typename ... Args> 
void Call (voidWrp const &, Args ... args) 
{ 
    PushArg(); 
    Call(std::forward<Args>(args)...); 
} 

int main() 
{ 
    Call("std::string value", 3, voidWrp{}, 6, 7L); 
} 

L'exemple programme imprime

- generic (T) PushArg 
- int PushArg 
- void PushArg 
- int PushArg 
- generic (T) PushArg