Implizite Template Instanzierung



  • Gibt es so etwas wie eine Implizite Template Instanzierung. Nachfolgendes Beispiel lässt sich anstandslos compilieren. Obwohl es das nicht sollte, solange keine explicite Instanzierung des Postincrement Operators für den Typ Test gemacht ist.

    template<typename T>
    inline T operator++(T& t, int) {
      t = static_cast<T>(static_cast<int>(t) + 1);
      return t;
    }
    
    enum Test {
      A0, A1, A2
    };
    
    Test Foo(Test t) {
      t++;  // Wird hier ein überladener Operator vom Compiler gebaut?
      return t;
    }
    

    Was geht hier vor?



  • Das ist immer so bei Funktionen.
    Der Compiler kann anhand der übergebenen Argumente Rückschlüsse auf die Typen ziehen.
    Das nennt sich template argument deduction.
    Sei froh drüber, die Alternative säh nicht schön aus:
    operator++<Test>(t, 0);



  • Nathan schrieb:

    Das ist immer so bei Funktionen.
    Der Compiler kann anhand der übergebenen Argumente Rückschlüsse auf die Typen ziehen.
    Das nennt sich template argument deduction.
    Sei froh drüber, die Alternative säh nicht schön aus:
    operator++<Test>(t, 0);

    Wenn das zum Standard gehört und keine Eigenheit des MS Compilers ist, dann wäre das sehr nett!

    Das heißt aber auch, dass ich keine Kontrolle mehr über die verwendeten Operatoren meiner neuen Typen habe, wenn der Compiler ein entsprechendes Template findet?



  • Man überlädt auch keine Operatoren als Templates im globalen Namensraum. Sonst muss man sich nicht wundern, wenn der Compiler versucht, diese zu verwenden...

    Was hast du genau vor? Willst du mit möglichst wenig Schreibaufwand neue Operatoren für Enums definieren?



  • Nexus schrieb:

    Man überlädt auch keine Operatoren als Templates im globalen Namensraum. Sonst muss man sich nicht wundern, wenn der Compiler versucht, diese zu verwenden...

    Was hast du genau vor? Willst du mit möglichst wenig Schreibaufwand neue Operatoren für Enums definieren?

    Naheliegend wäre Folgendes:

    #include "all_overloaded_operators.h"
    
    enum File {};
    enum Rank {};
    enum Square {};
    

    Und anschließend kann ich mit den "neu" definierten Typen rechnen wie mit Integers und man hat noch eine Typüberwachung:

    void Foo1(int, int, int);  // :-(
    void Foo2(File, Rank, Square);  // :-)
    

  • Mod

    Gibt es so etwas wie eine Implizite Template Instanzierung. Nachfolgendes Beispiel lässt sich anstandslos compilieren. Obwohl es das nicht sollte, solange keine explicite Instanzierung des Postincrement Operators für den Typ Test gemacht ist.

    Das musst du vertauschen. Funktionstemplates werden implizit instantiiert, sobald sie von der Overload-Resolution ausgewählt werden.

    Es gibt auch explizite Instantiierung, aber das bezeichnet folgendes:

    template<typename T>
    inline T operator++(T& t, int) {
      t = static_cast<T>(static_cast<int>(t) + 1);
      return t;
    }
    
    enum Test {
      A0, A1, A2
    };
    
    template Test operator++<Test>(Test&, int); // Explizite Instantiierungs-Definition
    


  • Wie wäre es damit:

    template <typename T>
            struct EnableOperator : public std::false_type
            {
            };
    
            template <typename T, typename ReturnType>
            using Enable = std::enable_if<EnableOperator<T>::value, ReturnType>;
    
    template <typename T>
    typename Enable<T, T> operator ++ (T& t) noexcept
    {
        t = static_cast<T>(static_cast<int>(t) + 1);
        return t;
    }
    

    Dann kannst du mit

    template <>
            struct EnableOperator<DeinTyp> : public std::true_type { };
    

    die operatoren für diesen Typ aktivieren, sie sind aber standardmäßig deaktiviert.



  • Das Problem mit den Enums hattest du doch schon vor vier Jahren...? 😮

    ..und auch wieder vor 2 Wochen. Was passt dir an den vorgeschlagenen Lösungen nicht? Das sauberste ist nach wie vor, eigene Klassentypen zu definieren.


  • Mod

    Nexus schrieb:

    Das Problem mit den Enums hattest du doch schon vor vier Jahren...? 😮

    Und schon in ähnlicher Form 9 Tage davor. Das macht ihn aber alles nicht satt 😋


Anmelden zum Antworten