template und der Fehler C 2075...HILFE!, BITTE!



  • N' Abend 😉 ,

    Ich hab folgendes Problem:
    Ich hab eine template Klasse CDemo. Diese allokiert Speicher für ein dynamisches Array im Kontruktor, siehe hier:

    template <class T>
    CDemo<T>::CDemo(Size sz, const T& data)
    {
       if(sz != 0)
       {
          _pData = new T[sz](data);
          // pData ist vom Typ: T*
          // ...
       }
    }
    

    Wenn ich die Klasse aber so instantiiere gibts gleich die Fehlermeldung dazu:

    CDemo<std::string> str(12, "Hallo");
    

    Fehlermeldung des Compilers (VS 2005 Express Edition):

    c:\...\CDemo.hpp(52) : error C2075: 'Target of operator new()': für die Initialisierung eines Arrays sind geschweifte Klammern erforderlich
    c:\...\CDemo.hpp(49): Bei der Kompilierung der Klassen-template der NMP::CDemo<Type>::CDemo(NMP::Size,const Type &)-Memberfunktion
    with
    [
    Type=std::string
    ]
    c:\...\main.cpp(13): Siehe Verweis auf die Instanziierung der gerade kompilierten Klassen-template "NMP::CDemo<Type>".
    with
    [
    Type=std::string
    ]

    Ich danke schonmal für eure Hilfen 🙂 .

    PS: Size ist unsigned long



  • Du kannst das Array in der Art nicht initialisieren. Wenn du das Template drumrum wegläßt bekommt du die gleiche Fehlermeldung.



  • [cpp]
    template <class T>
    CDemo<T>::CDemo(size_t sz, const T* data)
    {
    if(sz != 0)
    {
    T* _pData = new T[sz];
    memcpy(_pData, data, sz);
    }
    }
    so gehts z.B. 🙂



  • Txyz schrieb:

    so gehts z.B. 🙂

    Kommt sehr stark auf T an, ob das so geht. Vom fehlenden sizeof abgesehen, gibt es etliche Typen, die sich nicht mit memcpy kopieren lassen.



  • Txyz schrieb:

    so gehts z.B. 🙂

    Höchstwahrscheinlich nicht. Erstens kopiert memcpy() byteweise und füllt bestenfalls das erste Element mit deinem Wert auf. Und zweitens hat memvpy() keine Ahnung von Copy-Ctor'en und Zuweisungsoperatoren. Also sollte man besser C++ Mittel verwenden:

    CDemo<T>::CDemo(size_t sz, const T& data) 
    { 
      if(sz != 0) 
      { 
        _pData = new T[sz]; 
        fill_n(_pData,sz,data);
        //...
      } 
    }
    

    PS @TMP: Und du solltest daran denken, Copy-Ctor und op= für deine Klasse zu erzeugen.

    PPS: Und noch besser ist es, du verwendest statt des T* _pData einen std::vector



  • Hallo,

    CStoll schrieb:

    Erstens kopiert memcpy() byteweise und füllt bestenfalls das erste Element mit deinem Wert auf. Und zweitens hat memvpy() keine Ahnung von Copy-Ctor'en und Zuweisungsoperatoren. Also sollte man besser C++ Mittel verwenden:

    CDemo<T>::CDemo(size_t sz, const T& data) 
    { 
      if(sz != 0) 
      { 
        _pData = new T[sz]; 
        fill_n(_pData,sz,data);
        //...
      } 
    }
    

    Richtiger Ansatz, aber unnötig ineffizient. Ein std::vector wäre hier sicher die richtige Wahl, aber falls man, in einem akuten Anfall von NIHS, doch wieder alles selbst schreiben will, dann würde ich auf die Aufrufe des Standard-Ctors sowie die zusätzliche Anforderung, die dadurch an T gestellt wird, verzichten:

    Sprich:

    _pData = static_cast<T*>(operator new(sz * sizeof(T)));
    std::uninitialized_fill_n(_pData, sz, data);
    
    // Und später beim Löschen:
    operator delete(p);
    

    sz-Aufrufe des Standard-Ctors eingespart und kaum komplizierter.



  • Ja, das wäre die nächste Methode gewesen - aber ich bezweifle, daß ein Anfänger das schon kapiert 😉

    (übrigens habe ich das Gefühl, daß du gerade die Destruktor-Aufrufe für _pData unterschlagen hast)


Anmelden zum Antworten