Fragen zu enable_if-Ausdruck
-
Hallo,
ich lese grad ein bisschen über die SFINAE-Unterstützung vom VS2015 und bin dabei auf das folgende Bsp. gestoßen:
#include <type_traits> template<typename T, std::enable_if_t<std::is_integral<T>{}> * = nullptr> char f(T *); template<typename T> short f(...); int main() { static_assert(sizeof(f<int>(nullptr)) == sizeof(char), "fail"); static_assert(sizeof(f<int *>(nullptr)) == sizeof(short), "fail"); }
Ich verstehe dabei den enable_if_t-Ausdruck im ersten Template nicht richtig, und wollte fragen, ob mir das jemand erklären kann.
std::is_integral<T> ergibt einen Typ, die "{}" dahinter erzeugen doch eine Instanz von dem Typ und den übergebe ich als ersten Parameter an das enable_if, was ein bool erwartet? Wie passt das zusammen? Es müsste doch irgendwie ein "true" oder "false" an enable_if übergeben werden? Mit "is_integral_v" hätte ich es verstanden, weil das gibt ja ein "contexpr bool" zurück, aber so wie da dasteht, kapier ich das nicht.
VG
Pellaeon
-
In der CPP-Referenz zu is_integral steht:
Checks whether T is an integral type. Provides the member constant value which is equal to true, if T is the type bool, char, char16_t, char32_t, wchar_t, short, int, long, long long, or any implementation-defined extended integer types, including any signed, unsigned, and cv-qualified variants. Otherwise, value is equal to false.
-
Provides the member constant value which is equal to true
"value" wird oben ja eben nicht verwendet. Mit value wäre die Sache klar.
-
Ich denke, das ist was du suchst:
Member functions (Inherited from integral_constant):
operator bool
Returns value (public member function )
-
In dem Ausdruck oben steht doch nur
std::is_integral<T>{}
Also der Typ gefolgt von "{}". Letzteres erzeugt das Objekt, ein Aufruf von Operator () findet doch hier nicht statt?
-
Überfordere mich nicht
Ich lerne ja erst noch C++, aber das führt alles zum selben Ergebnis:
// integral_constant::operator value_type example #include <iostream> #include <type_traits> int main() { // is_integral<T> inherits from integral_constant if ( std::is_integral<int>() ) std::cout << "int is an integral type" << std::endl; if ( std::is_integral<int>{} ) std::cout << "int is an integral type" << std::endl; // same result as: if ( std::is_integral<int>::value ) std::cout << "int is an integral type" << std::endl; return 0; }
http://www.cplusplus.com/reference/type_traits/integral_constant/
http://www.cplusplus.com/reference/type_traits/integral_constant/operator%20value_type/Ein Stichwort wäre dann vielleicht noch "braced initialization"...
-
Es gibt einen constexpr cast-Operator nach value (=bool) für std::is_integral. Das funktioniert also:
constexpr bool a = std::is_integral<short*>{}; constexpr bool b = std::is_integral<short>{};
-
manni66 schrieb:
Es gibt einen constexpr cast-Operator nach value (=bool) für std::is_integral. Das funktioniert also:
constexpr bool a = std::is_integral<short*>{}; constexpr bool b = std::is_integral<short>{};
Ah ok, danke
@temin: ich wollte ja nicht wissen, ob es funktioniert, sondern warum
-
Pellaeon schrieb:
@temin: ich wollte ja nicht wissen, ob es funktioniert, sondern warum
Steht das nicht so im ersten meiner beiden Links?
Accessible as member integral_constant::value, or through type casting.
-
casting conversion.