Question

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 de n-uplets?

Était-ce utile?

La solution

  1. Impression sécurisée
  2. Transfert de nombreux arguments de constructeur arbitraires dans méthodes d'usine
  3. Le fait de disposer de classes arbitraires de base permet de définir et de supprimer des stratégies utiles .
  4. Initialisation en déplaçant objets typés hétérogènes directement dans un conteneur avec un constructeur de modèle variadique.
  5. Avoir un opérateur de littéral capable de calculer une valeur pour un littéral défini par l'utilisateur (tel que "10110b").

Échantillon à 3:

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

Échantillon à 4:

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

Échantillon à 5:

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

Voir cet exemple de code: ici

Autres conseils

Peut-être que la conférence d’Andrei Alexandrescu sur l’événement Going Native 2012 intéressera:

Voici la documentation.

  • printf
  • conforme au type

Permettre à des éléments comme Boost.Function de prendre un nombre arbitraire de paramètres

Je viens d'écrire un article sur la mise en oeuvre de plusieurs interfaces COM et le maintien de votre code compact et élégant avec les modèles variadiques C ++ 0x.

J'ai implémenté un NDArray (tableau N-dimensionnel) doté de la méthode setSizes avec un nombre variable d'arguments. Utiliser des arguments de modèles variadiques est plus sûr en termes de type que d’utiliser des arguments de fonctions variadiques. De plus, je peux contrôler le nombre de paramètres passés à cette fonction lors de la compilation uniquement avec des arguments de modèles variadiques.

void setSizes(uintmax_t currentSize) {
    static_assert(1 == NDimensions, "Invalid count of arguments given to setSizes.");

    size_ = currentSize;
    data_ = new NDArrayReferenceType[currentSize];
}

template <typename... Sizes>
void setSizes(uintmax_t currentSize, Sizes... sizes) {
    static_assert(sizeof...(Sizes) + 1 == NDimensions, "Invalid count of arguments given to setSizes.");

    size_ = currentSize;
    data_ = new NDArrayReferenceType[currentSize];

    for (uintmax_t i = 0; i < currentSize; i++) {
        data_[i]->setSizes(sizes...);
    }
}

J'ai également mis en place un wrapper de constructeur universel pour mon SmartPointer fabriqué par ses soins. Il englobe tous les constructeurs définis par l'utilisateur du type de pointeur brut.

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 non évident, il s’agit d’une partie de l’initialiseur du SmartPointer pour le cas où SmartPointer doit appeler automatiquement le constructeur du pointeur lors de l’acquisition du SmartPointer (RAII). Dans le cas de classes abstraites, il est impossible d'appeler le constructeur.

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

AbstractObject object = ConcreteObject(42, 42);

C'est comme C # et Java (mais avec RAII) et ça marche pour moi en C ++ / GCC 4.8 =)

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

L'impression en mode sûr a été mentionnée dans d'autres réponses, mais plus généralement, des modèles variadiques peuvent être utilisés pour implémenter des fonctions de formatage ne nécessitant aucune information de type via des spécificateurs de format. Par exemple, la bibliothèque de formats C ++ implémente des fonctions de formatage similaires à celles de Python str.format :

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

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

Ceci rend les spécificateurs printf tels que lld ou notoires PRIdPTR inutiles et non plus

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

on peut simplement utiliser

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

Clause de non-responsabilité : je suis l'auteur de cette bibliothèque

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top