In Template prüfen, ob Templatevariable ein Zeiger ist??



  • Das kannst du ganz einfach:

    template< typename type > struct is_pointer_t
    {
      enum{ value = 0 };
    };
    
    template< template type > struct is_pointer_t< type* >
    {
      enum{ value = 1 };
    };
    
    template< typename type > is_pointer_t< type > is_pointer( type t )
    {
      return is_pointer_t< type >();
    }
    
    //Benutzung is_pointer_t< char* >::value
    //oder is_pointer( argv ).value
    


  • @lolz, danke für den Tip!!!!!! werd's gleich mal implementieren



  • nightmare8019 schrieb:

    ich würd's gerne herausfinden OHNE die BOOST-Lib zu benutzen

    #include <tr1/type_traits>
    
    std::tr1::is_pointer<char*>::value
    


  • hmm...wenn ich so recht nachdenke, wird der Compiler trotzdem meckern. Ich kann zwar mit is_pointer(...) herausfinden, ob es ein Zeiger ist oder nicht, jedoch wird er im Code trotzdem an der Stelle

    ...
     delete Value;
    ...
    

    meckern. Oder sehe ich da etwas falsch?



  • ...es ist nämlich so, dass ich in einer eigenen Template-Listenklasse eine Methode namens DoAutoDelete() einfügen möchte. Und wenn in der Liste Zeiger auf Objekte abgelegt wurden, sollen diese Objekte auf Benutzerwunsch von der Templateklasse beim Destruktoraufruf automatisch gelöscht werden.
    das ist der eigentliche Hintergrund meiner Fragerei



  • Versuch mal folgendes:

    template <typename T> inline void cleanup( T& t )  { }
    template <typename T> inline void cleanup( T*& t ) { delete t; } // delete (T*)0; ist harmlos
    
    template<class T>
    bool CMyFirstTemplate<T>::Insert(T Value)
    {
    
      //...verarbeite Value und wenn Value ein Zeiger auf ein Objekt ist,
      //möchte ich den Speicher freigeben
    
      //if(Value != NULL)
      //    delete Value;
      cleanup(Value);
    }
    


  • hallo finix,

    danke für den Vorschlag, ich hab's eingebaut und eigentlich hätte es funktionieren müssen, aber zur Laufzeit springt das Programm immer in die erste Variante also:

    template <typename T> inline void cleanup( T& t )  { }
    

    und NICHT in:

    template <typename T> inline void cleanup( T*& t ) { delete t; }
    

    ich habe die Funktionen nicht als "inline" eingebaut aber das spielt wohl nix zur Sache..



  • Ich weiß es klingt albern, aber was ist, wenn du die Template-Deklaration für den Pointer zeilenmäßig über das andere machst?



  • Ich würde es in eine Klasse verlagern, da sind die Regeln nach denen ausgewählt wird wesentlich klarer. Das sollte gehen:

    template <class T> struct cleaner
    {
        static void clean(T const&){}
    }
    
    template <class T> struct cleaner<T*>
    {
        static void clean(T* p){ delete p; }
    }
    
    template <class T> void clean(T const& t)
    {
        cleaner<T>::clean(t);
    }
    


  • Hatte deinen letzten Post nicht gesehen. In dem Fall stimme ich natürlich hustbaer zu:

    template <typename T>
    class default_cleanup_policy
    {
    public:
      void cleanup( T const& t ) { }
    
    protected:
      ~default_cleanup_policy() { }
    };
    
    template <typename T>
    class default_cleanup_policy<T*>
    {
    public:
      void cleanup( T const* t ) { if (auto_delete_) delete t; }
    
      bool auto_delete() const             { return auto_delete_; }
      void auto_delete( bool auto_delete ) { auto_delete_ = auto_delete; }
    
    protected:
       default_cleanup_policy() : auto_delete_(true) { }
      ~default_cleanup_policy() { }
    
    private:
      bool  auto_delete_;
    };
    
    template <
      typename T,
      class cleanup_policy = default_cleanup_policy<T>
    >
    struct my_first_template : public cleanup_policy
    {
      bool tnsert( T const& value )
      {
        //...verarbeite Value und wenn Value ein Zeiger auf ein Objekt ist,
        //möchte ich den Speicher freigeben
    
        cleanup(value);
      }
    }
    


  • hallo finix & hustbaer! ich danke euch für die Hilfe!!
    es funktioniert wunderbar!

    @finix:
    jetzt hab ich aber noch ein paar fragen,
    warum funktioniert das Ganze, wenn man's mit Hilfe der zwei cleanup_policy - Klassen macht, nicht aber wenn man einfach zwei Methoden
    a la

    void cleanup(T const& t) {}
    void cleanup(T const* t) { if(auto_delete) delete t; }
    

    in die Klasse implementiert ?!



  • @finix:

    die zweite Frage bezieht sich auf Zeile 12 in deinem Quelltext.
    Kannst du mir kurz erläutern, was das <T>* nach dem Klassennamen bewirkt bzw. was es für die Klasse bedeutet?



  • @finix:

    ich hab mir die zweite Frage mit dem <T>[\b] gerade selbst beantwortet 🙂
    das die Klasse mit dem <T
    > am Ende des Klassennamens ist eine explizite Spezialisierung der Klasse [b]default_cleanup_policy** für einen Zeigertyp von T.
    richtig?



  • @finix:

    ich hab mir die zweite Frage mit dem <T>* gerade selbst beantwortet 🙂
    das die Klasse mit dem <T*> am Ende des Klassennamens ist eine explizite Spezialisierung der Klasse default_cleanup_policy für einen Zeigertyp von T.
    richtig?


Anmelden zum Antworten