2016-07-04 6 views

Antwort

8

Von cppreference:

[I] f die Variablendefinition T obj(std::declval<Args>()...); wohlgeformt ist, value gleich true, sonst valuefalse ist.

prüfen, ob Code wohlgeformt mit SFINAE Techniken durchgeführt wird, zum Beispiel des void_t<> Trick (erwarteten Teil der C++ 1z Standardbibliothek sein):

template <class...> 
using void_t = void; 

template <class, class T, class... Args> 
struct is_constructible_ : std::false_type {}; 

template <class T, class... Args> 
struct is_constructible_< 
    void_t<decltype(T(std::declval<Args>()...))>, 
T, Args...> : std::true_type {}; 

template <class T, class... Args> 
using is_constructible = is_constructible_<void_t<>, T, Args...>; 

Der using hoop -Hopping ist da, um das void_t<> Argument zuerst zu platzieren. Es kommt normalerweise mit einem Standardtyp, aber diese Position wird vom variadic Args Pack gehalten.

Wenn is_constructible_ für <void, T, Args...> instanziiert wird, versucht der Compiler zuerst, die Spezialisierung zu instanziieren. Dies ist nur dann erfolgreich, wenn der Inhalt von void_t<...> semantisch gültig ist, dh T(std::declval<Args>()...) korrekt ausgeführt werden kann - wie in den Anforderungen von is_constructible angegeben. Beachten Sie, dass ich eine temporäre anstelle einer lokalen Variable verwendet habe, aber meines Wissens ändern sich die Regeln nicht zwischen den beiden. Die Spezialisierung erbt von std::true_type, was eine truevalue ergibt.

Wenn die Spezialisierung nicht instanziiert werden kann (d. H. T(std::declval<Args>()...) ist nicht gültig), greift der Compiler auf die allgemeine Vorlage zurück, die immer instanziiert werden kann. Dieser erbt von std::false_type, was die falsevalue ergibt.

Live on Coliru

Genauere Züge, wie std::is_trivially_constructible, benötigen erweiterte Kenntnisse der Sprachregeln der Ausdruck, dessen Gültigkeit Handwerk sollte der Wert des Merkmals werden. Wenn dies innerhalb der Sprache nicht durchführbar ist, wie beispielsweise mit , dann muss der Compiler selbst eine intrinsische Funktion bereitstellen, um den Wert abzurufen.

+0

Das war eine ausgezeichnete Erklärung, danke! – Alex

+0

Dies ist nicht genau äquivalent zu 'std :: is_constructible', weil' T (Arg) 'äquivalent zu einer C-Style-Besetzung ist - also ist deine' is_constructible '' true', während die ' Std wird man falsch zurückgeben. –

Verwandte Themen