switch über Typen in C++



  • Hi zusammen,

    ich habe eine Frage, bei der ihr mir vielleicht helfen könntet...

    Ich würde gerne nach dem Typen eines template <typename T> prüfen und dann dementsprechende Funktionen ausführen.

    Als kleines Bleispiel Programm wie ich mir das vorstelle:

    #include <string>
    #include <typeinfo>
    
    template <typename T> std::string addIfString(T a, std::string b){
      std::string retVal;
      if(typeid(T).name() == typeid(std::string).name()){
        retVal = a;
        retVal.append(b);
      }
    return retVal;
    }
    

    gibt es da in c++ eine Möglichkeit über typen zu switchen ?
    wenn nicht nativ, gibt es Erweiterungen die mir das erlauben ?
    und wenn nicht über Typen dann über TemplateTypes ?

    (nutze gerade c++20)

    Grüße EvD

    Ps.: mir ist bewusst das der Code nicht geht, ich habe nur das zeigen wollen wie ich mir das vorstelle oder was ich erreichen will ohne zu wissen wie



  • @EvD

    Nein, das geht nicht. typeid liefert zwar schon zur Compile-time den Namen, aber der Vergleich passiert erst zur Laufzeit und ohne const-expr if muss der Code übersetzt werden, obwohl der Vergleich fehlschlägt. Der Compiler erzeugt dann Fehlermeldungen für alle Typen, die keine append( ... ) Funktion besitzen

    Dein Ziel kannst du mit Template-Spezialisierungen erreichen, die haben dann auch keinen Runtime-Overhead durch Stringvergleiche:

    template<typename T>
    std::string addIfString( T const& val, std::string const& b )
    {
       return b;
    }
    
    template<>
    std::string addIfString( std::string const& a, std::string const& b )
    {
       return a + b;
    }
    

    Edit:
    Eine Lösung mit if constexpr könnte so aussehen:

    template<typename T>
    std::string addIfString( T const& prefix, std::string const& text)
    {
        if constexpr( std::is_same<T,std::string>::value )  
        {
            return prefix + text;
        }
        else
        {
            return text;
        }
    }
    

    Was genau möchtest du denn erreichen?



  • uh, danke @DocShoe

    Ich bin dabei, ein Programm zu schreiben das über boost eine Kommunikation mit anderen Programmen aufbaut. die übermittelten Daten sind entweder vom typ T oder by default ein String. Wenn sie kein Strings sind muss das Verhalten bei eingaben mit einem function* übergeben werden (z.b. exit, reconect, ...). wenn es ein String ist habe ich Befehle vordefiniert und einprogrammiert

    Da ist deine erste Lösung am schönsten, werde ich auch so übernehmen. Zu wissen das es die 2. Lösung auch gibt ist aber trotzdem sehr schön und hilfreich 😃

    noch ein mal danke @DocShoe



  • @EvD
    Klingt nach etwas wo man u.U. schön mit "traits" arbeiten könnte.

    Sowas wie

    template <typename T>
    struct FooTraits;
    
    template <>
    struct FooTraits<std::string> {
        static std::string doSomething(std::string const& a, std::string const& b) {
            return a + b;
        }
    };
    
    // Weitere Spezialisierungen für weitere Typen
    
    template <typename T, typename Traits = FooTraits<T>>
    std::string someGenericFn(T const& a, std::string const& b) {
        return Traits::doSomething(a, b);
    }
    

Anmelden zum Antworten