2008-11-09 7 views
23

C++ 0x permettra au modèle de prendre un nombre arbitraire d'arguments. Quelle est la meilleure utilisation de cette fonctionnalité autre que l'implémentation des tuples?Modèles variadiques

Répondre

33
  1. typées printf
  2. Transmission des arguments du constructeur plusieurs arbitraires méthodes d'usine
  3. Ayant arbitraire base-classes permet de mettre et de retirer utiles politiques.
  4. Initialisation en déplaçant des objets typés hétérogènes directement dans un conteneur à l'aide d'un constructeur de template'd variadique.
  5. Avoir un opérateur littéral qui peut calculer une valeur pour un littéral défini par l'utilisateur (comme "10110b").

Exemple 3:

template<typename... T> struct flexible : T... { flexible(): T()... { } }; 

Exemple 4:

struct my_container { template<typename... T> my_container(T&&... t) { } }; 
my_container c = { a, b, c }; 

Exemple 5:

template<char... digits> 
int operator "" b() { return convert<digits...>::value; } 

Voir cet exemple code: here

+0

pas seulement printf de type-safe, mais des fonctions variadic de type-safe? –

2
  • typées printf
+0

Oui, mais je dois encore voir une implémentation très élégante de cela :-) –

+0

I thi Cet exemple spécifique est un peu dégénéré. Rappelez-vous que pour chaque instanciation le compilateur doit créer plus de code. pouvez-vous imaginer créer plus de 100 versions de printf pour chaque combinaison d'arguments possible? Oh le ballonnement! – shoosh

+2

@Shy: pas si toutes les versions sont des wrappers en ligne pour le * real * printf. – CesarB

2

Permettant des choses comme Boost.Function de prendre un nombre arbitraire de paramètres

2

Je viens d'écrire un article sur la façon d'implémenter plusieurs interfaces COM et de garder votre code compact et élégant avec des modèles variadiques C++ 0x.

0

Saisissez la sécurité de chaque appel avec un numéro d'argument dynamique.

+0

Pourriez-vous être plus précis? – alestanis

1

J'ai implémenté un NDArray (tableau N-dimentional) et il a la méthode setSizes avec le nombre variadic d'arguments. L'utilisation d'arguments de modèles variadiques est de type plus sûr que l'utilisation d'arguments de fonction variadiques, de plus je peux contrôler le nombre de paramètres passés à cette fonction au moment de la compilation uniquement avec des arguments de modèles variadiques. J'ai également mis en œuvre un wrapper de constructeur universel pour mon SmartPointer self-made. Il recouvre tout constructeur de type pointeur brut défini par l'utilisateur.

template <typename TSmartPointer, typename... Args> 
static inline void initialize(TSmartPointer *smartPointer, Args... args) { 
    smartPointer->pointer_ = new typename TSmartPointer::PointerType(std::forward<Args>(args)...); 
    smartPointer->__retain(); 
} 

Ce code semble être inobvious, cela fait partie de initialiseur du pointeur intelligent pour le cas si doit appeler automatiquement pointeur intelligent constructeur de pointeur à l'acquisition du pointeur intelligent (RAII). Dans le cas de classes abstraites, il est impossible d'appeler le constructeur.

Donc, si j'ai un type AbstractObject, qui est pointeur intelligent d'une classe abstraite, et le type ConcreteObject, qui est pointeur intelligent de la classe avec le constructeur qui prend deux ints, je peux écrire le code suivant:

AbstractObject object = ConcreteObject(42, 42); 

il est comme C# et Java (mais avec RAII) et cela fonctionne pour moi en C++/GCC 4,8 =)

3

Peut-être que le discours par Andrei Alexandrescu sur le Going événement natif 2012, ce sera de votre intérêt:

Here est la vid eo et Here la documentation.

0

D'autres réponses ont mentionné le type de sécurité printf, mais plus généralement des modèles variés peuvent être utilisés pour implémenter des fonctions de formatage qui ne nécessitent pas de passer des informations de type via des spécificateurs de format. Par exemple, les outils C++ Format library fonctions de formatage similaires à Python str.format:

fmt::print("I'd rather be {1} than {0}.", "right", "happy"); 

en plus de printf en toute sécurité. Les types d'arguments sont capturés automatiquement à l'aide de modèles variadiques dans C++ 11.

Cela fait printf comme spécificateurs lld ou notoire PRIdPTR inutile et au lieu de

std::printf("Local number: %" PRIdPTR "\n\n", someIntPtr); 

on peut simplement utiliser

fmt::printf("Local number: %d\n\n", someIntPtr); 

Responsabilité: Je suis l'auteur de cette bibliothèque