Domanda

C ++ 0x consentirà al modello di accettare un numero arbitrario di argomenti. Qual è il miglior uso di questa funzione oltre all'implementazione delle tuple?

È stato utile?

Soluzione

  1. printf sicuro per la stampa
  2. Inoltro di molti argomenti costruttivi arbitrari in metodi di fabbrica
  3. Avere arbitrari classi base consente di inserire e rimuovere utili criteri .
  4. Inizializzazione spostando oggetti tipizzati eterogenei direttamente in un contenitore con un costruttore di modelli variadici.
  5. Avere un operatore letterale in grado di calcolare un valore per un letterale definito dall'utente (come " 10110b ").

Campione di 3:

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

Campione di 4:

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

Campione a 5:

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

Vedi questo codice di esempio: qui

Altri suggerimenti

Forse il discorso di Andrei Alexandrescu sull'evento Going Native 2012 sarà di tuo interesse:

Qui e Qui la documentazione.

  • printf sicuro di tipo

Consentire a cose come Boost.Function di accettare un numero arbitrario di parametri

Ho appena scritto un articolo su come implementare più interfacce COM e conservare il tuo codice compatto ed elegante con i modelli variadic C ++ 0x.

Ho implementato un NDArray (array N-dimensionale) e ha il metodo setSizes con conteggio variabile degli argomenti. L'uso degli argomenti del modello variadico è più sicuro rispetto all'utilizzo degli argomenti della funzione variadica, inoltre posso controllare il conteggio dei parametri passati a questa funzione in tempo di compilazione solo con argomenti del modello variadico.

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...);
    }
}

Ho anche implementato un wrapper di costruzione universale per il mio SmartPointer fatto da sé. Si avvolge su tutto il costruttore definito dall'utente del tipo di puntatore non elaborato.

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();
}

Questo codice sembra essere obsoleto, fa parte dell'inizializzatore di SmartPointer nel caso in cui SmartPointer debba chiamare automaticamente il costruttore del puntatore all'acquisizione di SmartPointer (RAII). Nel caso di classi astratte non è possibile chiamare il costruttore.

Quindi, se ho un tipo AbstractObject, che è SmartPointer di una classe astratta, e il tipo ConcreteObject, che è SmartPointer di classe con costruttore che accetta due ints, posso scrivere il seguente codice:

AbstractObject object = ConcreteObject(42, 42);

È come C # e Java (ma con RAII) e funziona per me in C ++ / GCC 4.8 =)

Digitare safety di ogni chiamata con un numero di argomento dinamico.

La stampa di tipo sicuro è stata menzionata in altre risposte, ma in genere è possibile utilizzare modelli variadici per implementare funzioni di formattazione che non richiedono affatto il passaggio di informazioni sul tipo tramite identificatori di formato. Ad esempio, la libreria di formati C ++ implementa funzioni di formattazione simili a str.format :

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

oltre a printf sicuro. I tipi di argomenti vengono acquisiti automaticamente usando i modelli variadic in C ++ 11.

Ciò rende superflui gli identificatori di printf come lld o il noto PRIdPTR invece di

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

si può semplicemente usare

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

Disclaimer : sono l'autore di questa libreria

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top