Da Sie ganzzahlige Werte als Template-Parameter verwenden und arithmetische Berechnungen an ihnen vornehmen können, was ist die Motivation hinter boost :: mpl :: int_ <> und anderen Integralkonstanten? Gilt diese Motivation in C++ 11 noch?Warum hat Boost MPL Integralkonstanten?
Antwort
können Sie ganzzahlige Werte als Template-Parameter, aber Sie können nicht nehmen beide Typen und nicht-Typ Template-Parameter mit einer einzigen Vorlage. Lange Geschichte kurz, Behandlung Nicht-Typ-Vorlage Parameter als Typen ermöglicht es ihnen mit einer Vielzahl von Dingen innerhalb MPL verwendet werden.
Betrachten Sie zum Beispiel eine Metafunktion find
, die mit Typen arbeitet und nach einem gleichen Typ innerhalb einer Sequenz sucht. Wenn Sie es mit Nicht-Typ-Vorlage Parameter verwenden möchten, müssten Sie neue Algorithmen 'Überladungen', eine find_c
, für die Sie den Typ des Integralwerts manuell angeben müssen. Nun stellen Sie sich vor, Sie möchten, dass es mit gemischten integrierten Typen wie der Rest der Sprache funktioniert, oder dass Sie Typen und Nicht-Typen mischen möchten, erhalten Sie eine Explosion von "Überladungen", die auch passieren schwieriger zu verwenden, da Sie den Typ jedes Nicht-Typparameters überall angeben müssen.
Diese Motivation gilt immer noch in C++ 11.
wird diese Motivation zu C gelten nach wie vor ++ y und andere Version, es sei denn, wir haben einige neue Regel, die Umwandlung von nicht-Typ Template-Parameter-Typ Template-Parameter erlaubt. Wenn Sie beispielsweise 5
verwenden und die Vorlagenanforderungen einen Typ anfordern, instanziieren Sie ihn stattdessen mit std::integral_constant< int, 5 >
.
C++ y? Ich dachte, es war C++ 1y? –
tldr; Wenn ein Wert als Typ codiert wird, kann er an viel mehr Stellen als an einem einfachen Wert verwendet werden. Sie können Typen überladen, Sie können Werte nicht überladen.
K-Ballos Antwort ist großartig.
Es gibt noch etwas anderes, das ich für relevant halte. Die Integral-Konstantentypen sind nicht nur als Template-Parameter nützlich, sondern können auch als Funktionsargumente und Funktionsrückgabetypen nützlich sein (die C++ 11-Typen in meinen Beispielen verwenden, aber das gleiche Argument gilt für die Boost-Vorgänger):
template<typename R, typename... Args>
std::integral_constant<std::size_t, sizeof...(Args)>
arity(R (*)(Args...))
{ return {}; }
Diese Funktion benötigt einen Funktionszeiger und gibt einen Typ zurück, der die Anzahl der Argumente angibt, die die Funktion benötigt. Bevor wir constexpr
Funktionen hatten, gab es keine Möglichkeit, eine Funktion in einem konstanten Ausdruck aufzurufen, also Fragen zu stellen wie "wie viele Argumente nimmt dieser Funktionstyp?" Sie müssten einen Typ zurückgeben und den ganzzahligen Wert daraus extrahieren.
Auch mit constexpr
in der Sprache (was bedeutet, dass die obige Funktion könnte nur return sizeof...(Args);
und dieser Integer-Wert wäre zur Kompilierzeit verwendbar) gibt es immer noch gute Verwendungen für integrale Konstante Typen, z.Tag Disposition:
template<typename T>
void frobnicate(T&& t)
{
frob_impl(std::forward<T>(t), std::is_copy_constructible<T>{});
}
Diese frob_impl
Funktion kann als zweites Argument übergeben auf der Grundlage der integer_constant<bool, b>
Typ überlastet werden:
template<typename T>
void frob_impl(T&& t, std::true_type)
{
// do something
}
template<typename T>
void frob_impl(T&& t, std::false_type)
{
// do something else
}
Sie versuchen, etwas Ähnliches zu tun könnte, indem der boolean einen Template-Parameter:
aber es ist nicht möglich, eine Funktionsvorlage teilweise zu spezialisieren, so dass Sienicht machen konntenund frob_impl<false, T>
verschiedene Dinge tun. Überladen auf Typ der booleschen Konstante können Sie leicht verschiedene Dinge auf der Grundlage der Wert der "ist Kopie konstruierbar" Eigenschaft, und , dass ist immer noch sehr nützlich in C++ 11.
Eine andere Stelle, an der die Konstanten nützlich sind, ist das Implementieren von Merkmalen mit SFINAE. In C++ 03 bestand der herkömmliche Ansatz darin, Funktionen überladen zu haben, die zwei Typen mit unterschiedlichen Größen (z. B. int
und eine Struktur mit zwei int
s) zurückgeben und den "Wert" mit sizeof
testen. In C++ 11 können die Funktionen true_type
und false_type
zurückgeben, was viel aussagekräftiger ist, z. Eine Eigenschaft, die testet "Hat dieser Typ ein Element namens foo
?" kann die Funktion, die ein positives Ergebnis anzeigt, true_type
zurückgeben und die Funktion, die ein negatives Ergebnis anzeigt, zurückgeben false_type
, was könnte klarer als das sein?
Als Standardbibliothek Implementierer Ich mache sehr häufige Verwendung von true_type
und false_type
, weil eine Menge von Compile-Zeit „Fragen“ wahr/falsch beantwortet hat, aber wenn ich will etwas testen, die mehr als zwei haben kann andere Ergebnisse werde ich andere Spezialisierungen von integral_constant
verwenden.
Was ist los mit 'foo' und' bar'? : P –
Andere metasytaktische Variablen brauchen auch Liebe! –
- 1. Boost MPL verschachtelte Lambdas
- 2. boost :: mpl :: string size Fehlermeldungen
- 3. Boost MPL-Typen Vs Templates
- 4. boost :: mpl :: for_each ohne Instanziierung
- 5. Wie "verketten" boost :: mpl :: Vektoren
- 6. Boost MPL Placeholders und Lambda
- 7. Wie boost :: mpl :: inherit_linearly und boost :: mpl :: inherit richtig ketten, damit Platzhalter aufgelöst werden können?
- 8. Erweitern Boost-Variante mit einer MPL-Liste
- 9. Boost mpl list und auto_test_case_template Kompilierungsfehler
- 10. Wie durchläuft man eine boost :: mpl :: list?
- 11. Beispiele für den praktischen Einsatz von Boost :: MPL?
- 12. Wie boost :: mpl zum Verfassen von Richtlinien verwendet werden kann?
- 13. Permutationen einer Liste von Typen mit boost :: mpl
- 14. Verwenden von Boost MPL zum Berechnen von Längen von Vektoren
- 15. C++/Boost MPL: Strukturcode ebenfalls Haskell's Let, wo,
- 16. ziemlich Druck boost :: mpl :: string <...> Typen in gdb
- 17. Anwenden einer boost :: mpl :: Liste der Template-Parameter eines Typs
- 18. Boost Linking-Fehler für Boost-Dateisystem, warum?
- 19. Warum hat boost :: multi_array's ConstMultiArrayConcept ein NumDims Template-Argument?
- 20. Namespace Boost hat kein Mitglied
- 21. Paypal MPL iOS Fehler
- 22. Was ist der Punkt von "boost :: mpl :: identity <T> :: type" hier?
- 23. Ist es möglich boost :: mpl :: contains auf einem statischen Vektor_c zu verwenden?
- 24. Hat Boost Unit-Tests für sich selbst?
- 25. Hat der Standardkonstruktor von boost :: function die No-Throw-Garantie?
- 26. PayPal mpl Android, Initialisierungsproblem mit ENV_SANDBOX
- 27. Was bedeutet P :: ************ in Boost assert.hpp Datei?
- 28. mit boost :: interprocess in Klassenobjekt segfaults, warum?
- 29. boost :: enable_if Klasse Template-Methode
- 30. boost :: variant - Warum ein Template-Parameter eine höhere Priorität hat als ein Const-String-Parameter
Wenn dies wirklich von Interesse ist, lesen Sie das Buch "C++ Template Metaprogramming", von den Hauptautoren von Boost MPL, es erklärt die Motivationen hinter all diesen Arten von Dingen. Und dies gilt nicht nur für C++ 11, sondern wurde in C++ 11 mit [std :: integral_constant] (http://en.cppreference.com/w/cpp/types/integral_constant) zum Standard gemacht. –