std::is_same als SFINAE



  • Hallo,
    ich würde gerne prüfen, ob eine Template-Klasse einen bestimmten Repräsentanten hat (z. B. int64_toder double) 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


  • Mod

    1. Deine Bedingung ist gar nicht von T abhaengig
    2. Der Wert der Bedingung wird einfach verworfen
    3. 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:

    1. Deine Bedingung ist gar nicht von T abhaengig
    2. Der Wert der Bedingung wird einfach verworfen
    3. 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_if

    EDIT: es ist lange her; fixed 😃
    EDIT2: Btw ist es dann natürlich auch nicht mehr notwendig T beim Aufruf explizit zu definieren. Ein foo(a) reicht dann eigentlich auch schon aus.



  • @DNKpp Danke, werde ich gleich mal morgen ausprobieren! 😄


Anmelden zum Antworten