Umgehen mit Templates und Typ abhängigem Handeln



  • Hallo, ich habe eine Template Klasse, in welcher ich den Typ des Template Parameters überprüfe und dementsprechend handele.

    void ResourceManager<Resource, Identifier>::load(Identifier id, const std::string &filename)
        std::unique_ptr<Resource> resource(new Resource());
        if (std::is_same<Music, Resource>::value)
        {
            resource->openFromFile(filename);
        }
        else
        {
            resource->loadFromFile(filename);
        }
    

    Der einzige Unterschied ist also, dass man im Falle, dass der Resourcentyp Music ist, man openFromFile und ansonsten loadFromFile benutzt. Das compiliert so auch ohne Fehler, aber wenn ich eine Instanz erzeuge, die Methode aufrufe und Resource nicht Music ist, sondern Texture, gibt es folgenden Fehler

    error: ‘class Texture’ has no member named ‘openFromFile’; did you mean ‘loadFromFile’?
                 resource->openFromFile(filename);
                 ~~~~~~~~~~^~~~~~~~~~~~
    
    

    Kann ich dem Compiler irgendwie mitteilen, dass das ja auch nur ausgeführt wird, wenn der Typ dafür geeignet ist? Das er sich darum also keine Sorgen machen soll? Wenn nicht, gibt es eine andere Möglichkeit das zu umgehen?

    Danke für alle Antworten,

    Daniel



  • Das sollte mit einem if constexpr gehen - damit ignorierst du den Part, der schon anhand der Templates nicht ausgeführt werden kann. Wenn du das nicht nutzen kannst, dann musst du mit SFINAE die 2 Versionen des Codes basteln (oder ggf. einfacher, ich bin kein Template-Experte).



  • @wob Ja das funktioniert, danke. Warum funktioniert es so?



  • @daniel

    Weil der Compiler bei if constexpr zur Übersetzungszeit sieht, welche if-Bedingung zutrifft und er die anderen dann einfach verwerfen darf verwerfen muss.



  • @DocShoe Ah achso danke



  • Als Ergänzung zu dem was @DocShoe geschrieben hat bzw. "mimimi" Korrektur bezüglich der Wortwahl 🙂 : Der Compiler darf das sowieso immer wenn er kann. if constexpr unterscheidet sich darin, dass er es muss, und dass er dabei auch ignorieren muss wenn das was im nicht genommenen Zweig steht gleich überhaupt nicht kompilieren würde.


Anmelden zum Antworten