std::is_same als SFINAE
-
Hallo,
ich würde gerne prüfen, ob eine Template-Klasse einen bestimmten Repräsentanten hat (z. B.int64_t
oderdouble
) und abhängig davon eine bestimmte Funktion aufrufen.Hier mal Beispiel-Code:
#include <iostream> #include <cinttypes> #include <type_traits> template <typename T> struct TypeIdentity; template <> struct TypeIdentity<double> { using type = double; // Code }; template <> struct TypeIdentity<int> { using type = int; // Code }; template <typename T> auto foo(T& value) -> decltype(std::is_same<double, TypeIdentity<double>::type>::value, void()) { std::cout << "is double" << std::endl; } template <typename T> auto foo(T& value) -> decltype(std::is_same<int, TypeIdentity<int>::type>::value, void()) { std::cout << "is int" << std::endl; } int main() { double a = 10.0; int b = 1; foo<double>(a); foo<int>(b); return 0; }
Leider sagt mit der Compiler, ich würde
foo()
redefinieren. Weiß jemand weiter? Mit steht ein C++ 17 Compiler zur Verfügung.
Danke im Voraus.Steffo
-
- Deine Bedingung ist gar nicht von T abhaengig
- Der Wert der Bedingung wird einfach verworfen
- Da fehlt ein typename etc.
Probier mal
template <typename T> requires std::is_same<double, typename TypeIdentity<T>::type>::value void foo(T& value) { std::cout << "is double" << std::endl; }
-
@Columbo sagte in std::is_same als SFINAE:
- Deine Bedingung ist gar nicht von T abhaengig
- Der Wert der Bedingung wird einfach verworfen
- Da fehlt ein typename etc.
Probier mal
template <typename T> requires std::is_same<double, typename TypeIdentity<T>::type>::value void foo(T& value) { std::cout << "is double" << std::endl; }
requires
ist doch ein c++20 Keyword.template <typename T, std::enable_if_t<std::is_same_v<double, typename TypeIdentity<T>::type>, bool> = true> void foo(T& value) { std::cout << "is double" << std::endl; }
https://godbolt.org/z/9T5Pf4v17
https://en.cppreference.com/w/cpp/types/enable_ifEDIT: es ist lange her; fixed
EDIT2: Btw ist es dann natürlich auch nicht mehr notwendig T beim Aufruf explizit zu definieren. Einfoo(a)
reicht dann eigentlich auch schon aus.
-
@DNKpp Danke, werde ich gleich mal morgen ausprobieren!