templateklasse und inline



  • Hi ihrs!

    Ich hab da mal eine frage wie man inline bei template-klassen, deren funktionen nicht direkt in der klasse implementiert werden, benutzt wird.

    aktuell hab ich 3 varianten, aber ich weiß nicht welche die richtige ist.

    // Variante 1:
    template<class T> struct CKlasse
    {
        inline void foobar ();
    };
    
    template<class T> void CKlasse::foobar ()
    {
    }
    
    // Variante 2:
    template<class T> struct CKlasse
    {
        void foobar ();
    };
    
    template<class T> inline void CKlasse::foobar ()
    {
    }
    
    // Variante 2:
    template<class T> struct CKlasse
    {
        inline void foobar ();
    };
    
    template<class T> inline void CKlasse::foobar ()
    {
    }
    

    lustig ist, das ich inline überall hinschreiben kann, aber sowas wie virtual oder static nur bei der deklaration, aber nicht bei der implementierung. 🙂

    wie wirds nun richtig gemacht?



  • Hi,

    imho ist alles gleichgültig und richtig. Nur das bei dir ein <T> hinter CKlasse fehlt ...



  • Bei Templates spielt inline eigentlich keine Rolle, da die Definition sowieso im Header stehen muss.

    Auch bei normalen Klassen sollte man inline nicht zu früh einsetzen, weil der Compiler diesbezüglich gut optimieren kann. Man sollte es erst in Betracht ziehen, wenn es einem auf Nanosekunden drauf an kommt und man sich auch ernsthaft damit befasst (Profiler, Laufzeitanalyse, Benchmarks).



  • Nexus schrieb:

    Bei Templates spielt inline eigentlich keine Rolle, da die Definition sowieso im Header stehen muss.

    Ob die Definition im Header steht, oder nicht, hat überhaupt keine Auswirkung auf das inlining. Der Standard besagt lediglich, dass eine Definition einer Funktion in der Klassendefinition diese zu inline macht.

    ISO/IEC 14882 / 9.3/3 schrieb:

    An inline member function (whether static or nonstatic) may also be defined outside of its class definition
    provided either its declaration in the class definition or its definition outside of the class definition declares the function as inline.



  • drakon schrieb:

    Ob die Definition im Header steht, oder nicht, hat überhaupt keine Auswirkung auf das inlining.

    Ja, aber praktisch (modulare Programmierung) sieht es dann schon so aus, dass Inline-Methoden im Header definiert werden und "normale" ausserhalb (auf Nicht-Template-Klassen bezogen). Also eher der umgekehrte Schluss: Inlining hat Auswirkungen darauf, wo man die Definition hinzusetzen hat.

    Templates müssen ohne export sowieso vollständig im Header implementiert sein. Man kann aber das Schlüsselwort inline mit Templates nicht direkt in Verbindung bringen, oder? Bzw. dort bewirkt es gar nichts?



  • inlining hat nur wenig mit im Header oder nicht im Header zu tun. Es geht einzig darum, dass in der Klassendefinition definierte Methoden implizit inline deklariert sind.
    - Wenn du also zwar im Header, aber außerhalb der Klassendefinition die Methode definierst, ist sie nicht automatisch inline.
    - dass templates nicht in gesonderten Übersetzungseinheiten definiert werden können hat mit inlining nichts zu tun und hat auch keine Auswirkungen darauf.
    - (klassisches) inlining zur Compilezeit wird allerdings verhindert, wenn die Definition der Methode in einer anderen Übersetzungseinheit liegt als der Aufruf
    - es gibt allerdings Compiler die inlining zur Linkzeit ausführen können, oder bei speziellen Umgebungen (VMs etc.) auch später (z.B. wenn der Code dynamisch geladen wird)



  • Nexus schrieb:

    drakon schrieb:

    Ob die Definition im Header steht, oder nicht, hat überhaupt keine Auswirkung auf das inlining.

    Ja, aber praktisch (modulare Programmierung) sieht es dann schon so aus, dass Inline-Methoden im Header definiert werden und "normale" ausserhalb (auf Nicht-Template-Klassen bezogen). Also eher der umgekehrte Schluss: Inlining hat Auswirkungen darauf, wo man die Definition hinzusetzen hat.

    Templates müssen ohne export sowieso vollständig im Header implementiert sein. Man kann aber das Schlüsselwort inline mit Templates nicht direkt in Verbindung bringen, oder? Bzw. dort bewirkt es gar nichts?

    Nein und Nein.

    Du kannst (und das habe ich auch oft gesehen + mache ich auch selbst), dass, wenn inline angebracht ist das auch in der cpp gemacht wird und nicht um jeden Preis in den Header stopfen. (vor allem, wenn man getter und setter nicht in der Klassendefinition haben will).

    Doch auch in Verbindung mit Templates macht inlining durchaus Sinn und wird äquivalent zu Klassen gehandhabt.



  • drakon schrieb:

    Du kannst (und das habe ich auch oft gesehen + mache ich auch selbst), dass, wenn inline angebracht ist das auch in der cpp gemacht wird und nicht um jeden Preis in den Header stopfen. (vor allem, wenn man getter und setter nicht in der Klassendefinition haben will).

    Bei mehreren CPP-Dateien funktioniert das aber schlecht. Darauf wollte ich auch hinaus.

    // MyClass.hpp
    class MyClass
    {
    	public:
    		inline void Func();
    };
    
    // MyClass.cpp
    #include "MyClass.hpp"
    
    inline void MyClass::Func()
    {
    
    }
    
    // Main.cpp
    #include "MyClass.hpp"
    
    int main()
    {
    	MyClass x;
    	x.Func();
    }
    

    Diese Konstellation führt zu einem Linkerfehler, weil in Main.cpp ein nicht aufgelöster Verweis auf MyClass::Func() besteht.


Anmelden zum Antworten