Bisher kann ich nichts ELI5 online finden. Für ein Lernprojekt möchte ich mein eigenes is_constructible implementieren. Kann jemand bitte erklären, wie es funktioniert?Wie wird std :: is_constructible <T, Args> implementiert?
Antwort
Von cppreference:
[I] f die Variablendefinition
T obj(std::declval<Args>()...);
wohlgeformt ist,value
gleichtrue
, sonstvalue
false
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 true
value
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 false
value
ergibt.
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.
- 1. Wie std :: vector <std :: reference_wrapper <T>> konvertieren std :: vector <T>
- 2. std :: is_constructible gibt nicht das richtige Ergebnis
- 3. Wie wird `new (std :: nothrow)` implementiert?
- 4. Warum std :: shared_ptr <T> = std :: unique_ptr <T[]> Kompilierung, während std :: shared_ptr <T[]> = std :: unique_ptr <T[]> nicht?
- 5. Wie aus std :: optional <T>
- 6. Liste <T> implementiert SyncRoot nicht!
- 7. Wie wird sort für std :: deque implementiert?
- 8. Wo ist Enumeration <T> implementiert?
- 9. Warum implementiert List <T> IList <T>, ICollection <T> und IEnumerable <T>?
- 10. Unterschied zwischen std :: is_signed <T> und std :: numeric_limits <T> :: is_signed?
- 11. Warum implementiert IEnumerable <T> Add (T) nicht?
- 12. Wie std :: unordered_map implementiert
- 13. boost :: Variante <T> std :: string
- 14. C++ std :: vorwärts <T> vs static_cast <T>
- 15. Warum IList <T> implementieren IEnumerable <T> und ICollection <T> während ICollection <T> selbst IEnumerable implementiert <T>
- 16. Shared_ptr <T> Shared_ptr <T const> und Vektor Vektor <T><T const>
- 17. Wie implementiert IEnumerable <T> auf verschachtelten Wörterbuch?
- 18. Stack <T> implementiert ICollection, hat aber Methoden von ICollection <T>
- 19. Praktisch sicher anzunehmen sizeof (std :: unordered_map <std :: string, T>) ist für alle T gleich?
- 20. Warum wird std :: find so implementiert?
- 21. Warum sind Stack <T> und Queue <T> mit einem Array implementiert?
- 22. Std :: is_constructible auf Typ mit nicht öffentlichen Destruktor
- 23. Wie ist std :: has_virtual_destructor implementiert?
- 24. Sollte IEquatable <T> Equals() über IComparable <T>'s CompareTo() implementiert werden?
- 25. std :: list <std :: unique_ptr <T>>: passing es um
- 26. Wie wird die Liste <T> .IndexOf() in C# implementiert?
- 27. Fehler mit `std :: vector <std :: unique_ptr < T >>`
- 28. Erkennen, ob Typ implementiert ICollection <T>
- 29. std :: bewegen oder std :: vorwärts mit dem Parameter std :: unique_ptr <T> &&
- 30. Liste <T> .AsReadOnly() vs IReadOnlyCollection <T>
Das war eine ausgezeichnete Erklärung, danke! – Alex
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. –