C++ SFINAE / 44 C++ SFINAE inkl. std::enable_if Detlef Wilkening 08.01.2015.

44
C++ SFINAE http://www.wilkening-online.de 1 / 44 C++ SFINAE inkl. std::enable_if Detlef Wilkening http://www.wilkening-online.de 08.01.2015

Transcript of C++ SFINAE / 44 C++ SFINAE inkl. std::enable_if Detlef Wilkening 08.01.2015.

Page 1: C++ SFINAE  / 44 C++ SFINAE inkl. std::enable_if Detlef Wilkening  08.01.2015.

C++ SFINAE

http://www.wilkening-online.de 1 / 44

C++ SFINAEinkl. std::enable_if

Detlef Wilkeninghttp://www.wilkening-online.de08.01.2015

Page 2: C++ SFINAE  / 44 C++ SFINAE inkl. std::enable_if Detlef Wilkening  08.01.2015.

C++ SFINAE

http://www.wilkening-online.de 2 / 44

SFINAE SFINAE - "Substitution failure is not an error"

• Acronym wurde 2002 von David Vandevoorde eingeführt Im Standard gibt es den Begriff nicht

• Der Standard beschreibt in § 14.8.2 den Sachverhalt• Ohne aber ein explizites Acronym zu verwenden

Page 3: C++ SFINAE  / 44 C++ SFINAE inkl. std::enable_if Detlef Wilkening  08.01.2015.

C++ SFINAE

http://www.wilkening-online.de 3 / 44

Worum geht es eigentlich? Situation

• Eine Menge von überladenenen Funktionen• Alle sind Kandidaten für einen potentiellen Funktions-Aufruf

• Mindestens eine dieser Funktion ist ein Funktions-Template• Die Template-Argumente werden deduziert• Hierbei ergibt sich ein auf dem deduzierten Template-Typ beruhender Fehler

in der Funktions-Schnittstelle• Ein "Failure" beruhend auf der "Substitution"

=> Dies ist dann kein Compiler-Fehler

• Substitution Failure is not an Error

Sondern das Funktions-Template wird einfach aus der Menge der Kandidaten entfernt• Der Compile-Vorgang läuft einfach weiter

Page 4: C++ SFINAE  / 44 C++ SFINAE inkl. std::enable_if Detlef Wilkening  08.01.2015.

C++ SFINAE

http://www.wilkening-online.de 4 / 44

Das ist alles - " substitution failure is not an error" Fertig

Page 5: C++ SFINAE  / 44 C++ SFINAE inkl. std::enable_if Detlef Wilkening  08.01.2015.

C++ SFINAE

http://www.wilkening-online.de 5 / 44

Das ist alles - " substitution failure is not an error" Fertig

Okay, ein paar Beispiele und Anwendungen sind wohl noch ganz hilfreich…

Page 6: C++ SFINAE  / 44 C++ SFINAE inkl. std::enable_if Detlef Wilkening  08.01.2015.

C++ SFINAE

http://www.wilkening-online.de 6 / 44

Also eine Menge von überladenen Funktionen• Alle sind Kandidaten für einen potentiellen Funktions-Aufruf

Mindestens eine dieser Funktion ist ein Funktions-Template

void print(long l)

{

cout << "l: " << l << endl;

}

template<class T> void print(T t)

{

cout << "T: " << t << endl;

}

template<class T> void print(T* t)

{

cout << "T*: " << *t << endl;

}

int n = 42;

print(n); // => T: 42

print(&n); // => T*: 42

print(43L); // => l: 43

Page 7: C++ SFINAE  / 44 C++ SFINAE inkl. std::enable_if Detlef Wilkening  08.01.2015.

C++ SFINAE

http://www.wilkening-online.de 7 / 44

Die Template-Argumente werden deduziert Hierbei ergibt sich ein auf dem deduzierten Template-Typ

beruhender Fehler in der Funktions-Schnittstelle• Ein "Failure" beruhend auf der "Substitution"

=> Dies ist dann kein Compiler-Fehler• Substitution Failure is not an Error• Das Funktions-Template wird einfach aus der Menge der Kandidaten entfernt• SFINAE schlägt während der Funktions-Überladen Auflösung zu

// Zusaetzlich

template<class T> void print(typename T::type t)

{

cout << "T::type: " << t << endl;

}

// => Kein Problem

int n = 42;

print(n); // => T: 42

print(&n); // => T*: 42

print(43L); // => l: 43

Page 8: C++ SFINAE  / 44 C++ SFINAE inkl. std::enable_if Detlef Wilkening  08.01.2015.

C++ SFINAE

http://www.wilkening-online.de 8 / 44

SFINAE wurde genau dafür eingeführt Bestehender Code sollte nicht ungültig werden, wenn zusätzlich

(z.B. durch einen erweiterten Header) ein Funktions-Template in die Menge der potentiellen Aufruf-Kandidaten hinzukommt, das nach der Typ-Deduktion nicht "okay" ist.

// Zusaetzlich

template<class T> void print(typename T::type t)

{

cout << "T::type: " << t << endl;

}

// => Kein Problem

Page 9: C++ SFINAE  / 44 C++ SFINAE inkl. std::enable_if Detlef Wilkening  08.01.2015.

C++ SFINAE

http://www.wilkening-online.de 9 / 44

Ganz nebenbei: Wie spricht man unser neues Funktions-Template an?

Page 10: C++ SFINAE  / 44 C++ SFINAE inkl. std::enable_if Detlef Wilkening  08.01.2015.

C++ SFINAE

http://www.wilkening-online.de 10 / 44

void print(long l)

{

cout << "l: " << l << endl;

}

template<class T> void print(T t)

{

cout << "T: " << t << endl;

}

template<class T> void print(T* t)

{

cout << "T*: " << *t << endl;

}

template<class T> void print(typename T::type t)

{

cout << "T::type: " << t << endl;

}

Page 11: C++ SFINAE  / 44 C++ SFINAE inkl. std::enable_if Detlef Wilkening  08.01.2015.

C++ SFINAE

http://www.wilkening-online.de 11 / 44

struct A

{

typedef bool type;

};

int main()

{

cout << boolalpha;

int n = 42;

print(n); // => T: 42

print(&n); // => T*: 42

print(43L); // => long: 43

print(false); // => T: false

print<A>(true); // => T::type: true

}

Page 12: C++ SFINAE  / 44 C++ SFINAE inkl. std::enable_if Detlef Wilkening  08.01.2015.

C++ SFINAE

http://www.wilkening-online.de 12 / 44

SFINAE bezieht sich nicht nur auf Failures in den Parametern• Sondern auch auf

• Alle Typen im Funktions-Typ (Parameter, Rückgabe,…)• Alle Typen in der Template-Parameter Deklaration• Seit C++11 auch auf alle Ausdrücke in den Template- und Funktions-Typen

Achtung - wird von MSVS noch nicht unterstützt

Aber nicht in der Implementierung!

// Zusaetzlich auch kein Problem

// - Return-Typ wirft Funktions-Template raus

template<class T> typename T::type print(T t)

{

cout << "T=>: " << t << endl;

}

Page 13: C++ SFINAE  / 44 C++ SFINAE inkl. std::enable_if Detlef Wilkening  08.01.2015.

C++ SFINAE

http://www.wilkening-online.de 13 / 44

Nicht in der Implementierung• Substitution-Failure dort sind kein SFINAE

// Aenderung am bisherigem Funktions-Template in der Implementierung

template<class T> void print(T t)

{

typename T::type x; // <= kein SFINAE => Compiler-Fehler

cout << "T: " << t << endl;

}

Page 14: C++ SFINAE  / 44 C++ SFINAE inkl. std::enable_if Detlef Wilkening  08.01.2015.

C++ SFINAE

http://www.wilkening-online.de 14 / 44

Weitere SFINAE Fehler• Array von void, Referenzen, Größe "0", usw. zu erzeugen• Typ ungleich Enums und Klasse links von ::• Nutzung eines Members, den es nicht gibt bzw. der sich in Typ oder

Template-Parametern unterscheidet• Zeiger auf Referenz• Referenz auf void• Zeiger auf Member von T, wenn T keine Klasse ist• Ungültiger Typ für einen Non-Type Template-Parameter• Unerlaubte Konvertierungen in Template-Ausdrücken oder Ausdrücken in

Funktions-Deklarationen• Funktions-Typ mit Rückgabe von Arrays• Funktions-Typ mit cv-Qualifier (C++11)• Funktions-Typ mit Rückgabe abstrakte Klasse (C++11)• Instanziierung von Template-Parameter Packs mit unterschiedlicher Länge

(C+11)

Page 15: C++ SFINAE  / 44 C++ SFINAE inkl. std::enable_if Detlef Wilkening  08.01.2015.

C++ SFINAE

http://www.wilkening-online.de 15 / 44

Beispiel für Array der Größe 0• Beispiel von cppreference• http://en.cppreference.com/w/cpp/language/sfinae

// Diese Funktion wird genommen, wenn I gerade ist

template<int I> void div(char(*)[I % 2 == 0] = 0)

{

}

// Diese Funktion wird genommen, wenn I ungerade ist

template<int I> void div(char(*)[I % 2 == 1] = 0)

{

}

Page 16: C++ SFINAE  / 44 C++ SFINAE inkl. std::enable_if Detlef Wilkening  08.01.2015.

C++ SFINAE

http://www.wilkening-online.de 16 / 44

Kann man denn auch was Sinnvolles mit SFINAE machen?

Oder ist es nur ein Sprach-Feature, damit bestehender Code nicht bricht?• Letzlich der Sinn hinter § 14.8.2

Page 17: C++ SFINAE  / 44 C++ SFINAE inkl. std::enable_if Detlef Wilkening  08.01.2015.

C++ SFINAE

http://www.wilkening-online.de 17 / 44

Es wird interessant, wenn man Funktions-Templates mit einer allgemeinen Funktion mit einem Ellipsis Parameter kombiniert• Denn:

• Der Ellipsis Parameter hat die niedrigste Stufe in der Überladen-Hierarchie• => Kommt also nur zum Tragen, wenn nichts anderes greift• Aber er greift bei jedem Argument

• Aber Beispiel (nächste Folie) sieht (noch) langweilig aus

Page 18: C++ SFINAE  / 44 C++ SFINAE inkl. std::enable_if Detlef Wilkening  08.01.2015.

C++ SFINAE

http://www.wilkening-online.de 18 / 44

void fct(...)

{

cout << "Ellipsis" << endl;

}

template<class T> void fct(typename T::type t)

{

cout << "T::type " << t << endl;

}

struct A

{

typedef int type;

};

fct(42); // => Ellipsis

fct<A>(42); // => T::type 42

Page 19: C++ SFINAE  / 44 C++ SFINAE inkl. std::enable_if Detlef Wilkening  08.01.2015.

C++ SFINAE

http://www.wilkening-online.de 19 / 44

Wenn man jetzt auch noch die Ellipsis-Funktion zu einem Funktions-Template macht...• Damit man auch sie mit einer expliziten Typ-Deduktion aufrufen kann

template<class> void fct(...)

{

cout << "Ellipsis" << endl;

}

template<class T> void fct(typename T::type t)

{

cout << "T::type " << t << endl;

}

struct A { typedef int type; };

fct<int>(42); // => Ellipsis

fct<A>(42); // => T::type 42

Page 20: C++ SFINAE  / 44 C++ SFINAE inkl. std::enable_if Detlef Wilkening  08.01.2015.

C++ SFINAE

http://www.wilkening-online.de 20 / 44

Dann kann man jetzt z.B. einen Member-Checker bauen• Einen Compile-Time Member-Checker• Daher zur Compile-Zeit checken, ob ein Member vorhanden ist

• Und abhängig davon eine Compile-Zeit Konstante setzen

Oder auch Checks für viele andere Dinge

Einfaches Beispiel:• Hat ein Typ eine "Init" Funktion?• Abhängig vom Ergebnis könnte man dann die Funktion aufrufen oder nicht• Außerdem kann die Lösung so nicht mit Vererbung umgehen• Und ist auch nicht gut parameterisierbar• Ist halt nur ein einfaches Beispiel

Page 21: C++ SFINAE  / 44 C++ SFINAE inkl. std::enable_if Detlef Wilkening  08.01.2015.

C++ SFINAE

http://www.wilkening-online.de 21 / 44

template<typename T> struct HasInitFct

{

typedef char Yes[1];

typedef char No[2];

template<typename U, U> struct SignatureCheck;

template<typename V> static

Yes& check(SignatureCheck<void(T::*)(), &V::init>*);

template<typename> static

No& check(...);

static bool const result = (sizeof(check<T>(0)) == 1);

};

Page 22: C++ SFINAE  / 44 C++ SFINAE inkl. std::enable_if Detlef Wilkening  08.01.2015.

C++ SFINAE

http://www.wilkening-online.de 22 / 44

Hinweise• Das Ergebnis findet sich in der Variable „result“• Für die Unterscheidung werden die Aufrufe der überladenen Funktion

„check“ genommen• Damit klar ist, welche Funktion genommen wird, wird die Rückgabe eindeutig

unterscheidbar gemacht.• Yes ist genau 1 Byte groß• No ist genau 2 Byte groß

• Da Funktionen keine Arrays zurückgeben können, werden Referenzen zurückgegeben

• Die Ellipse paßt auf jeden Zeiger, aber der konkrete Zeiger in der Yes-Check Funktion paßt prinzipiell besser

• Hat der Typ T keine passende Funktion, so ist die Yes-Funktions-Signatur ungültig und die Funktion wird ausgeschlossen (SFINAE)

Page 23: C++ SFINAE  / 44 C++ SFINAE inkl. std::enable_if Detlef Wilkening  08.01.2015.

C++ SFINAE

http://www.wilkening-online.de 23 / 44

struct NoInit

{

};

struct WithInit

{

void init() {}

};

cout << boolalpha;

cout << "NoInit -> " << HasInitFct<NoInit>::result; // => false

cout << "WithInit -> " << HasInitFct<WithInit>::result; // => true

Page 24: C++ SFINAE  / 44 C++ SFINAE inkl. std::enable_if Detlef Wilkening  08.01.2015.

C++ SFINAE

http://www.wilkening-online.de 24 / 44

Und wie ruft man jetzt "init()" auf bzw. nicht? Dafür benötigt man etwas TMP

• Aufrufe z.B. in Klassen legen• Statische Funktion

• In Abhängigkeit von HasInitFct<>::result den Typ wählen• TMP If

• Aufruft der Funktion über den Typ

Page 25: C++ SFINAE  / 44 C++ SFINAE inkl. std::enable_if Detlef Wilkening  08.01.2015.

C++ SFINAE

http://www.wilkening-online.de 25 / 44

struct InitNo{ template<class T> static void init(T&) { }};

struct InitYes{ template<class T> static void init(T& t) { t.init(); }};

Page 26: C++ SFINAE  / 44 C++ SFINAE inkl. std::enable_if Detlef Wilkening  08.01.2015.

C++ SFINAE

http://www.wilkening-online.de 26 / 44

template<bool Expr, class TrueType, class FalseType> struct TypeIf{ typedef TrueType Type;};

template<class TrueType, class FalseType> struct TypeIf<false, TrueType, FalseType>{ typedef FalseType Type;};

template<class T> void init (T& t){ typedef typename TypeIf<HasInitFct<T>::result, InitYes, InitNo>::Type Type; Type::init(t);}

Page 27: C++ SFINAE  / 44 C++ SFINAE inkl. std::enable_if Detlef Wilkening  08.01.2015.

C++ SFINAE

http://www.wilkening-online.de 27 / 44

Und was ist das Problem mit der Vererbung?

Page 28: C++ SFINAE  / 44 C++ SFINAE inkl. std::enable_if Detlef Wilkening  08.01.2015.

C++ SFINAE

http://www.wilkening-online.de 28 / 44

struct NoInit{};

struct WithInit{ void init() {}};

struct InheritedInit : WithInit{};

struct DoubleInheritedInit : InheritedInit{};

Page 29: C++ SFINAE  / 44 C++ SFINAE inkl. std::enable_if Detlef Wilkening  08.01.2015.

C++ SFINAE

http://www.wilkening-online.de 29 / 44

cout << boolalpha;cout << "NoInit -> " << HasInitFct<NoInit>::result;cout << "WithInit -> " << HasInitFct<WithInit>::result;cout << " InhInit -> " << HasInitFct<Inhe...Init>::result;cout << "DInhInit -> " << HasInitFct<Doubl...Init>::result;

=>

NoInit -> falseWithInit -> true InhInit -> falseDInhInit -> false

Page 30: C++ SFINAE  / 44 C++ SFINAE inkl. std::enable_if Detlef Wilkening  08.01.2015.

C++ SFINAE

http://www.wilkening-online.de 30 / 44

Lösung• Eigene lokale Klasse, die von T und einer lokalen Mixin-Klasse erbt• Die Mixin-Klasse hat die Funktion• => Die lokale Mixed Klasse erbt die Funktion von der Mixin-Klasse• Hat aber T die Funktion auch (direkt oder geerbt),

dann wird die Funktion zweimal geerbt• => Ohne klare Entscheidung für eine der geerbten Funktionen ist das

fehlerhaft => SFINAE => Funktion wird ausgeschlossen => Ellipsen-Check Funktion gewinnt

Achtung• Yes und No sind hier zwischen den Check-Funktionen getauscht worden

Page 31: C++ SFINAE  / 44 C++ SFINAE inkl. std::enable_if Detlef Wilkening  08.01.2015.

C++ SFINAE

http://www.wilkening-online.de 31 / 44

template<typename T> struct HasRealInitFct{ typedef char Yes[1]; typedef char No[2];

struct Mixin { void init(){} }; struct Mixed : public T, public Mixin {}; template<typename U, U> struct SigCheck;

template<typename V> static No& check(SigCheck<void(Mixin::*)(), &V::init>*); template<typename> static Yes& check(...);

static bool const result = (sizeof(check<Mixed>(0))==1);};

Page 32: C++ SFINAE  / 44 C++ SFINAE inkl. std::enable_if Detlef Wilkening  08.01.2015.

C++ SFINAE

http://www.wilkening-online.de 32 / 44

cout << boolalpha;cout << "NoInit -> " << HasRealInitFct<NoInit>::result;cout << "WithInit -> " << HasRealInitFct<WithInit>::result;cout << " InhInit -> " << HasRealInitFct<I...Init>::result;cout << "DInhInit -> " << HasRealInitFct<D...Init>::result;

=>

NoInit -> falseWithInit -> true InhInit -> trueDInhInit -> true

Page 33: C++ SFINAE  / 44 C++ SFINAE inkl. std::enable_if Detlef Wilkening  08.01.2015.

C++ SFINAE

http://www.wilkening-online.de 33 / 44

Achtung, nochmal der Hinweis SFINAE ist ein Sprachmittel Kein Idiom Auch wenn es manchmal als solches bezeichnet wird

• Ist z.B. Teil des Wikibooks "More C++ Idioms"• http://en.wikibooks.org/wiki/More_C%2B%2B_Idioms

Aber es gibt Idioms, die auf SFINAE aufsetzen• Z.B. "Member Detector"

• http://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Member_Detector• Ein einfaches Beispiel dafür hatten wir gerade

• Oder Enable-If• Siehe nächste Folien

Page 34: C++ SFINAE  / 44 C++ SFINAE inkl. std::enable_if Detlef Wilkening  08.01.2015.

C++ SFINAE

http://www.wilkening-online.de 34 / 44

Die vielleicht wichtigste Anwendung von SFINAE ist "enable_if"• Vorhanden in Boost, aber seit C++11 auch im Standard• Enable-If erlaubt Funktionen zu überladen, die in Abhängigkeit von einer

user-definierten Compile-Zeit Bedingung aufgerufen werden• Header <type_traits>

Beispiele• 1) Nutzung von SFINAE über den Rückgabe-Typ• 2) Wie 1 nur ohne void• 3) Wie 2 mit C++14• 4) Nutzung von SFINAE über einen Extra-Parameter

Page 35: C++ SFINAE  / 44 C++ SFINAE inkl. std::enable_if Detlef Wilkening  08.01.2015.

C++ SFINAE

http://www.wilkening-online.de 35 / 44

template<class T>

typename enable_if<is_pod<T>::value, void>::type reset(T& t)

{

cout << "POD\n";

memset(&t, 0, sizeof(T));

}

template<class T>

typename enable_if<!is_pod<T>::value, void>::type reset(T& t)

{

cout << "Kein POD\n";

t.reset();

}

Page 36: C++ SFINAE  / 44 C++ SFINAE inkl. std::enable_if Detlef Wilkening  08.01.2015.

C++ SFINAE

http://www.wilkening-online.de 36 / 44

struct A

{

A() {}

void reset() { s=""; }

string s;

};

int main()

{

int n;

reset(n); // => POD

A a;

reset(a); // => Kein POD

}

Page 37: C++ SFINAE  / 44 C++ SFINAE inkl. std::enable_if Detlef Wilkening  08.01.2015.

C++ SFINAE

http://www.wilkening-online.de 37 / 44

Man kann das "void" sogar weglassen => Default Template-Argument

template<class T>

typename enable_if<is_pod<T>::value>::type reset(T& t)

{

cout << "POD\n";

memset(&t, 0, sizeof(T));

}

template<class T>

typename enable_if<!is_pod<T>::value>::type reset(T& t)

{

cout << "Kein POD\n";

t.reset();

}

Page 38: C++ SFINAE  / 44 C++ SFINAE inkl. std::enable_if Detlef Wilkening  08.01.2015.

C++ SFINAE

http://www.wilkening-online.de 38 / 44

In C++14 gibt es zusätzlich "enable_if_t"• Resultat-Typ "type" muß nicht ausgwiesen werden• using enable_if_t = typename enable_if<B,T>::type;• Warum gibt es eigentlich kein "is_pod_v"?

template<class T>

typename enable_if_t<is_pod<T>::value> reset(T& t)

{

cout << "POD\n";

memset(&t, 0, sizeof(T));

}

template<class T>

typename enable_if_t<!is_pod<T>::value> reset(T& t)

{

cout << "Kein POD\n";

t.reset();

}

Page 39: C++ SFINAE  / 44 C++ SFINAE inkl. std::enable_if Detlef Wilkening  08.01.2015.

C++ SFINAE

http://www.wilkening-online.de 39 / 44

Man kann natürlich auch einen Parameter für SFINAE nutzen Da das T selber nicht geht, z.B. ein extra T* mit Default-Argument

template<class T> void reset(T& t,

typename enable_if<is_pod<T>::value, T>::type* = nullptr)

{

cout << "POD\n";

memset(&t, 0, sizeof(T));

}

template<class T> void reset(T& t,

typename enable_if<!is_pod<T>::value, T>::type* = nullptr)

{

cout << "Kein POD\n";

t.reset();

}

Page 40: C++ SFINAE  / 44 C++ SFINAE inkl. std::enable_if Detlef Wilkening  08.01.2015.

C++ SFINAE

http://www.wilkening-online.de 40 / 44

Mögliche Implementierung von "enable_if"• Von cppreference.com• http://en.cppreference.com/w/cpp/types/enable_if

template<bool B, class T = void> struct enable_if

{

typedef T type;

};  

template<class T> struct enable_if<false, T>

{

};

Page 41: C++ SFINAE  / 44 C++ SFINAE inkl. std::enable_if Detlef Wilkening  08.01.2015.

C++ SFINAE

http://www.wilkening-online.de 41 / 44

SFINAE in Kombination mit enable_if und den Type-Traits von C++ liefert viele mächtige Compile-Zeit Entscheidungen• Siehe Header Type-Traits bzw. § 20.10• Beispiele:

is_void

is_null_pointer

is_integral

is_floating_point

is_array

is_pointer

is_lvalue_reference

is_rvalue_reference

is_member_object_pointer

is_member_function_pointer

is_enum

is_union

is_class

is_function

is_standard_layout

is_pod

is_literal_type

is_empty

is_polymorphic

is_abstract

is_final

is_trivially_assignable

is_trivially_copy_assignable

is_trivially_move_assignable

is_trivially_destructible

is_reference

is_arithmetic

is_fundamental

is_object

is_scalar

is_compound

is_member_pointer

is_const

is_volatile

is_trivial

is_trivially_copyable

Page 42: C++ SFINAE  / 44 C++ SFINAE inkl. std::enable_if Detlef Wilkening  08.01.2015.

C++ SFINAE

http://www.wilkening-online.de 42 / 44

Bücher

• Nicolai M. Josuttis & David Vandevoorde• C++ Templates• The Complete Guide• Addison-Wesley Longman• ISBN: 978-0201734843• 1. Auflage, November 2002• Neue Auflage für C++14 in Vorbereitung

2. Auflage, Juli 2015 ISBN: 978-0321714121

• Davide Di Gennaro• Advanced C++ Metaprogramming• CreateSpace Independent Publishing Platform• ISBN: 978-1460966167• 1. Auflage, Juni 2011

Page 43: C++ SFINAE  / 44 C++ SFINAE inkl. std::enable_if Detlef Wilkening  08.01.2015.

C++ SFINAE

http://www.wilkening-online.de 43 / 44

Links• http://en.wikipedia.org/wiki/Substitution_failure_is_not_an_error• http://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/SFINAE• http://en.cppreference.com/w/cpp/language/sfinae• http://en.cppreference.com/w/cpp/types/enable_if• http://eli.thegreenplace.net/2014/sfinae-and-enable_if/• http://nonchalantlytyped.net/blog/2012/06/27/yet-another-sfinae/• http://blog.olivierlanglois.net/index.php/2007/09/01/

what_is_the_c_sfinae_principle• http://blog.cplusplus-soup.com/2006/09/learning-about-sfinae.html• http://www.ddj.com/cpp/184401659 • http://www.semantics.org/once_weakly/w02_SFINAE.pdf • http://people.mpi-inf.mpg.de/~kettner/courses/lib_design_03/notes/

meta.html#Constraining• http://flamingdangerzone.com/cxx11/2013/02/11/to-sfinae-or-not-to-

sfinae.html

Page 44: C++ SFINAE  / 44 C++ SFINAE inkl. std::enable_if Detlef Wilkening  08.01.2015.

C++ SFINAE

http://www.wilkening-online.de 44 / 44

Fragen?