Frage
C ++ 0x ermöglicht Vorlage eine beliebige Anzahl von Argumenten zu übernehmen. Was ist die beste Verwendung dieses Merkmals als Tupel implementieren?
Lösung
- Typ-safe printf
- Forwarding beliebig vieler Konstruktorargumente in Factory-Methoden
- Mit beliebigen Basis-Klassen ermöglicht setzen und Entfernen nützlich Politik .
- initialisieren, indem heterogene typisierte Objekte direkt in einen Behälter durch einen variadische template'd Konstruktor hat.
- Literaloperator Mit , die einen Wert für einen Benutzer berechnen kann wörtlichen definiert (wie "10110b").
Beispiel 3:
template<typename... T> struct flexible : T... { flexible(): T()... { } };
Beispiel 4:
struct my_container { template<typename... T> my_container(T&&... t) { } };
my_container c = { a, b, c };
Beispiel 5:
template<char... digits>
int operator "" b() { return convert<digits...>::value; }
Sehen Sie diesen Beispielcode: hier
Andere Tipps
- Typ-safe
printf
Unter Berücksichtigung Dinge wie Boost.Function nehmen eine beliebige Anzahl von Parametern
Ich schrieb gerade einen Artikel auf, wie mehrere COM-Schnittstellen zu implementieren und halten Ihr Code kompakt und elegant mit C ++ 0x variadische Vorlagen.
Ich habe eine NDArray (N-dimensionales Array) implementiert, und es wird die Methode mit SetSizes variadische Zählung von Argumenten. Mit variadische Vorlage Argumente geben sicherer als variadische Funktionsargumente verwenden, zudem ich Anzahl der Parameter für diese Funktion in der Kompilierung weitergegeben steuern kann nur mit variadische Vorlage Argumente.
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...);
}
}
Ich habe auch einen universellen Konstruktor Wrapper für meine selbstgemachten Intelligenter Zeiger umgesetzt. Es wickelt über alle benutzerdefinierten Konstruktor vom Typ von Rohzeiger.
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();
}
Dieser Code ist inobvious scheint, das ist ein Teil von initializer des Intelligenter Zeiger für den Fall, ob Intelligenter Zeiger automatisch den Konstruktor der Zeiger auf den Erwerb des Intelligenter Zeiger (RAH) nennen sollte. Im Falle der abstrakten Klassen ist es nicht in der Lage den Konstruktor aufrufen.
Also, wenn ich einen Typ AbstractObject haben, die Intelligenter Zeiger einer abstrakten Klasse ist, und die Art ConcreteObject, die Intelligenter Zeiger der Klasse mit Konstruktor ist, die zwei Ints nimmt, kann ich folgenden Code schreiben:
AbstractObject object = ConcreteObject(42, 42);
Es ist wie C # und Java (aber mit RAH) und es funktioniert für mich in C ++ / GCC 4.8 =)
Typ Sicherheit jeden Anruf mit dynamischem Argumente Nummer.
Typ-safe printf hat in anderen Antworten erwähnt, sondern allgemeine variadische Vorlagen können verwendet werden Formatierungsfunktionen zu implementieren, die erfordern nicht bei allen Arten von Informationen über den Formatbezeich vorbei. Zum Beispiel kann der C ++ Format Bibliothek Formatierungsfunktionen ähnlich wie der Python implementiert str.format :
fmt::print("I'd rather be {1} than {0}.", "right", "happy");
zusätzlich zu sicher printf. Die Typen der Argumente werden unter Verwendung von 11 variadische Vorlagen in C ++ automatisch erfasst.
Das macht printf Bezeich wie lld
oder berüchtigt PRIdPTR
unnötig und anstelle von
std::printf("Local number: %" PRIdPTR "\n\n", someIntPtr);
kann man einfach nutzen
fmt::printf("Local number: %d\n\n", someIntPtr);
Hinweis : Ich bin der Autor dieser Bibliothek