Typename bei Template-Klasse



  • Servus, und erstmal sorry für die späte Antwort.

    Hmm, ja diese Form der Spezialisierung habe ich bereits. Dennoch stoße ich leider innerhalb des Templates auf das geschilderte Problem.

    Um bei deinen Beispiel zu bleiben

    template <typename T> class foo<T*> : public foo<T>
    {
    public:
      void B()
      {
        cout<<"Speziell für Pointer"<<endl;
        T newObj = new T(*initObj); // <-- hier dann nach wie vor das Probelm
      }
    };
    

    An obiger Stelle habe ich dann das Problem, wenn ich ein neues Object des Typen
    erstellen will. Denn im Klartext habe ich ja z.B. im Quellcode stehen

    int* t = new int*(*initObj);
    

    Womit ja eine 'int**' erhalte. Da ich ja nicht weiß was für einen Typen ich in das Template bekomme, müsste ich ja über 'typinfo' und 'typeid(T).name()' abfragen welchen Type ich habe damit ich in einer z.B. einer If-Abfrage welchen Type er nehmen soll etwa so in der Art..

    template <typename T> class foo<T*> : public foo<T>
    {
    public:
      void B()
      {
        cout<<"Speziell für Pointer"<<endl;
        wxString typname = typeid(T).name();
        if (typename.IsSameAs(_T("int*"))) 
        {
            T newObj = new int(*initObj);
        }
        else if (typename.IsSameAs(_T("eigeneKlasse*"))) 
             {
                 T newObj = new eigeneKlasse(*initObj);
             }
       // usw. für andere Typen
      }
    };
    

    Wäre aber eine unschöne Lösung meiner Meinung nach. Darum meine Hoffnung das es vielleicht doch eine Möglichkeit gegeben hätte beim 'typename' einfach das '*' wegzubekommen. Naja werde mal noch ein wenig in den MSDN-Seiten suchen. Ansonsten muss ich mir wohl doch überlegen den Typen ohne den *-Operator zu übergeben.

    Aber vielen Dank für die Antwort...
    Mfg



  • Ohne Dein Problem jetzt komplett verstanden zu haben, vielleicht hilft Dir ja remove_pointer< T > weiter aus boost.type_traits weiter.

    typedef remove_pointer< int* >::type my_int;
    typedef remove_pointer< int >::type my_int2;
    

    my_int und my_int2 sind jetzt die gleichen Typen, nämlich ganz normale Integer.



  • Ja sowas habe ich gesucht. Besten Dank.

    Bekomm jetzt zwar den C1189 - Error. Aber hab jetzt mal einen Ansatzpunkt. Da suchen ma mal was Google und das Forum dazu ausspuckt.

    Erstmal besten Dank.. 🙂



  • Du musst hier natürlich auch typename verwenden. VC++ treibt da leider ziemlich krumme Dinge mit typename.

    typedef typename remove_pointer<T*>::type my_type;
    

    Sowas selbst zu bauen ist aber auch relativ einfach:

    template <typename T>
    struct remove_pointer
    {
    	typedef T type;
    };
    
    template <typename T>
    struct remove_pointer<T*>
    {
    	typedef T type;
    };
    

    (ungetestet, sollte aber so funzen) 😉



  • 314159265358979 schrieb:

    Du musst hier natürlich auch typename verwenden. VC++ treibt da leider ziemlich krumme Dinge mit typename.

    Naja, innerhalb eines Templates muss dass typename da hin, ansonsten natürlich nicht.



  • headmyshoulder schrieb:

    314159265358979 schrieb:

    Du musst hier natürlich auch typename verwenden. VC++ treibt da leider ziemlich krumme Dinge mit typename.

    Naja, innerhalb eines Templates muss dass typename da hin, ansonsten natürlich nicht.

    Jo, klar 😉



  • Ollow_AM schrieb:

    template <typename T> class foo<T*> : public foo<T>
    {
    public:
      void B()
      {
        cout<<"Speziell für Pointer"<<endl;
        wxString typname = typeid(T).name();
        if (typename.IsSameAs(_T("int*"))) 
        {
            T newObj = new int(*initObj);
        }
        else if (typename.IsSameAs(_T("eigeneKlasse*"))) 
             {
                 T newObj = new eigeneKlasse(*initObj);
             }
       // usw. für andere Typen
      }
    };
    

    Wäre aber eine unschöne Lösung meiner Meinung nach. Darum meine Hoffnung das es vielleicht doch eine Möglichkeit gegeben hätte beim 'typename' einfach das '*' wegzubekommen.

    Verstehe gerade das Problem nicht. In der Spezialisierung "T*" steht T ja nicht mehr für den Zeiger Typ ("eigeneKlasse*"), sondern nur mehr für den Typ ("eigeneKlasse").
    Demzufolge muss/kann der Code auch so aussehen:

    template <typename T> class foo<T*> : public foo<T>
    {
    public:
      void B()
      {
        cout<<"Speziell für Pointer"<<endl;
    
        T* newObj = new T(*initObj);
      }
    };
    


  • @ 314159265358979 :
    Jap wunderbar, der Code funzt einwandfrei. Weil die 'std::tr1::remove_pointer' wollte er nicht. Besten Dank....

    @ hustbaer:
    Jap aber nur solange keiner versucht das Template mit einen 'eigeneKlasse*' zu füttern.

    Aber mit den dem 'remove_pointer' funktionen klappt das ja jetzt einwandfrei.

    Besten Dank an alle 🙂



  • Ollow_AM schrieb:

    @ hustbaer:
    Jap aber nur solange keiner versucht das Template mit einen 'eigeneKlasse*' zu füttern.

    Was wäre denn dann das Problem?

    Ollow_AM schrieb:

    An obiger Stelle habe ich dann das Problem, wenn ich ein neues Object des Typen
    erstellen will. Denn im Klartext habe ich ja z.B. im Quellcode stehen

    int* t = new int*(*initObj);
    

    Hast du nicht. Wenn du foo<int*> instantiierst, greift die Spezialisierung foo<T*> und T ist int, nicht int*. Der code wird also zu

    int t = new int(*initObj);
    


  • Okay, jetzt verstehe ich es.
    Das bedeutet wenn ich

    myTemplateClass<int> a;
    // bzw
    myTemplateClass<int*> b;
    

    aufrufe erkennt er das das eine ein 'Zeigertype' ist geht direkt auf die Speziealisierung. Wenn ich das richtig verstehe ist das "ähnlich" wie bei Funktionen mit verschiednen Signaturen die ja ebenfalls unterschieden werden.

    Hmm, dann werd ich mir das nochmal durch den Kopf gehen lassen. Wie ich es machen werde.

    Mit dem

    template <typename T> 
    struct rm_ptr
    {
    	typedef T type;
    };
    template <typename T>
    struct rm_ptr<T*>
    {
    	typedef T type;
    };
    

    klappt nämlich alles einwandfrei. Aber werd das ganze mal überdenken, auf welche Art und Weise ich es lösen werde.
    Mfg



  • Ollow_AM schrieb:

    Mit dem

    template <typename T> 
    struct rm_ptr
    {
    	typedef T type;
    };
    template <typename T>
    struct rm_ptr<T*>
    {
    	typedef T type;
    };
    

    klappt nämlich alles einwandfrei.

    Weil es genau das selbe macht 😉



  • Uhiala, jetzt wo du es sagst. Wird´s mir klar... 😮

    "Man sieht den Wald vor lauter Bäumen nicht.." kann ich da nur sagen.. 👍


Anmelden zum Antworten