Typ eines Template Parameter



  • hi,

    wie kann ich abhängig vom Typ eines Template seinen Wert initialisieren ?

    using namespace std;
    
    template<typename T1> class cTest
    {
        private:
            T1 _v1;
    
        public:
            cTest()
            {
                _v1 = 0;      // für int
                //_v1 = "";   // für string ??
    
            }
    
    };
    
    int main()
    {
    
        cTest<int> ival;
        //cTest<string> sval;
    
    }
    


  • Mit der Konstruktor-Initialisierungsliste. Dort rufst du den Standardkonstruktor (bzw. für int die Null-Initialisierung) auf.

    cTest() : _v1()
    {
    }
    

    <💡>



  • template<typename T1> class cTest
    {
        private:
            T1 _v1;
    
        public:
            cTest() : _v1()
            {
            }
    
    };
    
    int main()
    {
    	cTest<int> ival;
    	cTest<string> sval;
    }
    


  • Kommt darauf an, wie gravierend die Unterscheidung ist, die Faustregel wäre erstmal versuchen, eine Lösung ohne Spezialisierung zu finden. In deinem Fall wäre das eben der Default-Ctor.

    Spezialisierung wäre dann die Alternative, wenn es wirklich nicht mehr anders geht.
    Beispiel:

    #include <iostream>
    
    template<typename T>
    struct Test
    {
            T var;
    
            Test();
    };
    
    template<typename T>
    Test<T>::Test():
            var(0){}
    template<>
    Test<std::string>::Test():
            var("LoL!"){}
    
    int main()
    {
            Test<std::string> a;
            std::cout << a.var;
    }
    


  • Danke.



  • 🤡 Ich möchte noch anmerken: Wenn eine Klasse keinen selbst-definierten Konstruktor hat, werden temporäre Objekte automatisch value-initialized. 🤡



  • out schrieb:

    🤡 Ich möchte noch anmerken: Wenn eine Klasse keinen selbst-definierten Konstruktor hat, werden temporäre Objekte automatisch value-initialized. 🤡

    Naja... ich kenne jetzt keinen Weg zu einem temporären Objekt zu kommen ohne dass entweder
    * Ein anderes Objekt kopiert wird oder
    * Die Value-Initialization-Syntax "T()" verwendet wird

    Von daher ist die Aussage ziemlich sinnfrei ... oder hab ich da jetzt was falsch verstanden?

    Die einzige C++ Eigenart die mir hierzu noch einfällt ist dass Value-Initialization von PODs == Zero-Initialization aller Member~~, wenn der POD keinen Default-Konstruktor hat.~~ (Darf er sowieso nicht, dann wäre er kein POD mehr)
    Das kann zu üblen Überraschungen führen, wenn Klassen unbeabsichtigt von PODs zu non-PODs werden...



  • hustbaer schrieb:

    wenn der POD keinen Default-Konstruktor hat.

    Ich bin jetzt mit dem C++11 noch nciht so weit, dass ich solche Dinge nachgeschaut hätte - aber IIRC gehörte zur Definition eines POD, dass er garkeinen Konstruktor hat oder nicht?



  • pumuckl schrieb:

    hustbaer schrieb:

    wenn der POD keinen Default-Konstruktor hat.

    Ich bin jetzt mit dem C++11 noch nciht so weit, dass ich solche Dinge nachgeschaut hätte - aber IIRC gehörte zur Definition eines POD, dass er garkeinen Konstruktor hat oder nicht?

    Jup. Ich könnte dir jetzt den Standardteil liefern, aber ich bin zu faul... 😃



  • Ach, was solls.

    §9.10 schrieb:

    A POD struct is a non-union class that is both a trivial class and a standard-layout class

    ➡

    §9.6 schrieb:

    A trivial class is a class that has a trivial default constructor (12.1) and is trivially copyable.

    ➡

    §9.6 schrieb:

    A trivially copyable class is a class that:
    — has no non-trivial copy constructors (12.8),
    — has no non-trivial move constructors (12.8),
    — has no non-trivial copy assignment operators (13.5.3, 12.8),
    — has no non-trivial move assignment operators (13.5.3, 12.8), and
    — has a trivial destructor (12.4).

    ➡ Fazit: Ein POD hat keine User-definierten Konstruktoren oder Destruktoren.
    Alle Standard-Zitate sind N3337 entnommen.

    P.S.: Die Aussage, dass er keinen Konstruktor hat, ist natürlich Blödsinn 😃


  • Mod

    out schrieb:

    🤡 Ich möchte noch anmerken: Wenn eine Klasse keinen selbst-definierten Konstruktor hat, werden temporäre Objekte automatisch value-initialized. 🤡

    Eine gewagte Behauptung.

    struct foo
    {
        char x;
        int:13;
    };
    foo bar() { foo x = { 42 }; return x; }
    
    bar(); // Rückgabewert nicht value-initialisiert, padding und das unbenannte Bitfeld könnten von 0 verschieden sein
    foo x = { 42 };
    foo(x); // nicht value-initialisiert, padding und das unbenannte Bitfeld könnten von 0 verschieden sein
    
    foo{ 42 }; // auch nicht value-initialisiert
    


  • pumuckl schrieb:

    hustbaer schrieb:

    wenn der POD keinen Default-Konstruktor hat.

    Ich bin jetzt mit dem C++11 noch nciht so weit, dass ich solche Dinge nachgeschaut hätte - aber IIRC gehörte zur Definition eines POD, dass er garkeinen Konstruktor hat oder nicht?

    Ich hab's noch nicht im neuen Standard nachgelesen, ... irgendwas sollte bezüglich Definition von PODs geändert werden, und ich war mir nimmer sicher was.
    (Ich glaube es gibt um das Erlauben von public non-virtual Member-Funktionen oder sowas, weiss nimmer).

    Daher hab ich das "wenn" einfach mal dazugeschrieben.



  • Wie ist es denn jetzt eigentlich. Wenn man von C++ spricht ist, da jetzt Standard, immer C++11 gemeint, wenn nix anderes dazu geschrieben wurde, oder?



  • Butterbrot schrieb:

    Wie ist es denn jetzt eigentlich. Wenn man von C++ spricht ist, da jetzt Standard, immer C++11 gemeint, wenn nix anderes dazu geschrieben wurde, oder?

    Jein. Zur Zeit sollte man nur dann pauschal von C++ sprechen, wenns bei dem Thema keine relevanten Unterschiede zwischen C++11 oder C++03 gibt. Sonst sollte man immer dazu sagen, wenns um etwas geht, was erst ab C++11 gilt, oder (seltener) was mit C++11 nicht mehr so gilt.



  • Das ist doch genau der Fall, für den man in C++11 die „Uniform Initialization“ eingeführt hat:

    template<typename T1> class cTest
    {
        private:
            T1 _v1;
    
        public:
            cTest() : _v1{}  // TADA
            {
            }
    
    };
    


  • Butterbrot schrieb:

    Wie ist es denn jetzt eigentlich. Wenn man von C++ spricht ist, da jetzt Standard, immer C++11 gemeint, wenn nix anderes dazu geschrieben wurde, oder?

    Wenn Sone schreibt, dann ja. Ansonsten: nein! Es ist zwar der neue Standard, aber er wird nur von den aktuellsten Compilern untertsützt und das auch nicht immer vollständig.

    Und da es viele gibt, die eben nicht mit diesen Compilern arbeiten und dementsprechend die neuen Features nicht nutzen können, sollte das explizit erwähnt werden.



  • daddy_felix schrieb:

    Wenn Sone schreibt, dann ja.

    Nein. Lies meinen Post nochmal in Ruhe durch, und dann bemerkst du, was ich nebenbei dazu geschrieben hab'.

    @ipsec: Finde mir mal das Wort "Uniform initialization" im Standard 😃


Log in to reply