Ihr Code zeigt drei neue C++ 11 Funktionen: variadische Vorlagen, Benutzerdefinierte Literale und statische Aussagen.
Die allgemeine variadic Klassenvorlage spezifiziert null oder mehr Argumente, die spezialisierten Versionen eins oder mehrere und genau eins.
// digits can be the empty set, so 0 or more arguments
template<char... digits>
struct conv2bin;
// digits can be the empty set, so 1 or more arguments
template<char high, char... digits>
struct conv2bin<high, digits...>
// fully specialized for 1 argument
template<char high>
struct conv2bin<high>
Die vollständige Syntax von variadische Vorlagen ist ein wenig schrullig, Wikipedia auf es einen ordentlichen Artikel hat. Es ist besonders nützlich für ein anderes C++ 11-Feature: perfekte Weiterleitung einer variadic Anzahl von Funktionsargumenten.
Das exotisch aussehende int operator "" _b()
definiert ein benutzerdefiniertes Literal, mit dem Sie Ihren Typen und Ausdrücken eigene Einheiten hinzufügen können. Es bedeutet einfach, dass ganze Zahlen gefolgt von _b
mit einer bestimmten "Einheit" markiert sind. Siehe hierzu question für weitere Details. Ein praktischer Vorteil wäre, zukünftige Mars Lander Crashes zu vermeiden (wo SI und imperiale Einheiten in ihrer Landing Software gemischt wurden, ohne dass der Compiler dies diagnostizieren konnte).
Die static_assert
tut genau das, was Sie denken, es tut: es behauptet seinen Zustand statisch, d. H. Bei kompilieren-Zeit. Wenn die Assertion fehlschlägt, wird die Kompilierung angehalten. Dies ist eine großartige Möglichkeit, Fehler so schnell wie möglich zu erkennen.
UPDATE
Spezialisierung von variadische Vorlagen sehr überraschend sein kann, wenn Sie teilweise überlappende Bereiche der Argumente haben: die null oder mehr Argumente Version wird nur eine leere Liste passen in Ihrem Beispiel (im Fall würden Sie haben eine Definition dafür gegeben).
#include <iostream>
template<int... Args>
struct Test
{
enum { value = 0 };
};
template<int I, int... Args>
struct Test<I, Args...>
{
enum { value = 2 };
};
template<int I>
struct Test<I>
{
enum { value = 1 };
};
int main()
{
std::cout << Test<>::value << "\n"; // matches zero or more version
std::cout << Test<0>::value << "\n"; // matches single argument version
std::cout << Test<0, 0>::value << "\n"; // matches one or more version, not the zero or more one!
}
Ausgabe auf LiveWorkSpace.
Das ist natürlich ein Beispiel für die allgemeine Regel für die partielle Template-Spezialisierung, die besagt, dass die spezialisierteste Version wird ausgewählt werden (ein oder-mehr ist spezialisierter als Null-oder-mehr, da diese Dose immer dort verwendet werden, wo das erstere möglich ist, aber nicht umgekehrt). Aber weil variadische Vorlagen sich oft nicht so "sichtbar" voneinander unterscheiden, sollten Sie mit ihren Teilspezialisierungen besonders vorsichtig sein.
Ja, Entschuldigung für den Fehler – Paul
Werfen Sie einen Blick auf diese Links. Sie sollten alles erklären. - [Variadic Templates] (http://www.cplusplus.com/articles/EhvU7k9E/) - [Benutzerdefinierte Literale] (http://en.cppreference.com/w/cpp/language/user_literal) - [Statisch Behauptung] (http://en.cppreference.com/w/cpp/language/static_assert) –