2009-07-20 8 views

Répondre

16

Pour C++ non géré avec la même syntaxe pratique, non.

Mais il existe un support pour variable argument lists pour les fonctions en C++.

Fondamentalement, vous déclarez une fonction avec le dernier paramètre étant une ellipse (...), et dans le corps de la fonction, utilisez les appels va_start()/va_arg() pour analyser la liste de paramètres fournie.

Ce mécanisme est de type pas sûr, et l'appelant pourrait passer quoi que ce soit, vous devriez donc documenter clairement l'interface publique de la fonction et ce que vous attendez à être transmis.

pour le code managé C++, voir les commentaires de Reed .

19

Oui. En C++ standard, vous pouvez utiliser va_arg et la syntaxe ... Voir MSDN for details.

Pour C++/CLI, il existe un raccourci pour cela.

vous faites cela comme:

void TheMethod(String^ firstArgument, ... array<Object^>^ variableArgs); 

Voir cette blog post for details.

+0

Bon à savoir à ce sujet ... ne savait pas que C++ avait cette extension pour code managé. – LBushkin

+0

@LBushkin: mise à jour vers la meilleure syntaxe. –

0

Il y a une bibliothèque named parameters en boost (si j'ai bien compris ce que sont les paramètres en C#). Il permet d'écrire des fonctions comme celles-ci:

int y = lib::f(_name = "bob", _index = 2); 

Impossible d'indiquer si un surdébit significatif est impliqué.

+1

Les paramètres C# ne sont pas nommés params - c'est une liste d'arguments de longueur variable. –

3

De nos jours, avec le C++ moderne, vous pouvez utiliser des pratiques modernes de type sécurité pour les fonctions variées.

Utilisez soit des modèles variadique ou std :: initializer_list si tous vos arguments ont le même type

Avec modèle variadique, vous utilisez récursion passer par une liste de paramètres variadique. Variadique exemple de modèle:

template<class T> 
void MyFoo(T arg) 
{ 
    DoSomething(arg); 
} 
template<class T, class... R> 
void MyFoo(T arg, R... rest) 
{ 
    DoSomething(arg); 
    // If "rest" only has one argument, it will call the above function 
    // Otherwise, it will call this function again, with the first argument 
    // from "rest" becoming "arg" 
    MyFoo(rest...); 
} 

int main() 
{ 
    MyFoo(2, 5.f, 'a'); 
} 

Cela garantit que si DoSomething, ou tout autre code que vous exécutez avant l'appel récursif à MyFoo, a une surcharge pour le type de chaque argument que vous passez à la fonction MyFoo, que la surcharge exacte être appelé.

Avec std :: initializer_list, vous utiliser une simple boucle foreach pour passer par les arguments

template<class T> 
void MyFoo(std::initializer_list<T> args) 
{ 
    for(auto&& arg : args) 
    { 
     DoSomething(arg); 
    } 
} 
int main() 
{ 
    MyFoo({2, 4, 5, 8, 1, 0}); // All the arguments have to have the same type 
} 
+0

Il peut être intéressant de noter que vous pouvez également combiner des modèles 'static_assert' et variadic pour créer votre liste d'initialiseurs flexible. F.ex. vous pouvez combiner 'std :: is_base_of' avec un static_assert sur' T' dans votre exemple pour vous assurer que tous les types sont dérivés d'une certaine classe de base. – atlaste

Questions connexes