Template, Objekt/Pointer unterscheiden..



  • Bei einzelnen Funktionen mit Überladung:

    template <typename T>
    void do_stuff(T* obj)
    {
        // Zeigervariante
    }
    
    template <typename T>
    void do_stuff(T& obj)
    {
        // Referenzvariante
    }
    

    Bei Klassen mithilfe einer Spzialisierung:

    template <typename T>
    struct foo { ... };
    
    template <typename T>
    struct foo<T*> { ... };
    

    Ich kann mir nicht vorstellen, dass Hackers Ding da irgendwie ne Hilfe ist. Zumal es das Ding sowieso schon unter std::is_pointer in <type_traits> gibt.

    Edit: Und in deinem Fall würde ich einfach einen zweiten Ctor basteln, der einen const T* nimmt.

    Edit 2: Achso, ich seh schon das Problem. Ist schon etwas spät 🤡
    Ich würde wohl zwei Ctoren schreiben, die so aussehen:

    ItemHandle(typename std::remove_pointer<T>::type* ptr);
    ItemHandle(typename std::remove_pointer<T>::type& ref);
    

  • Mod

    template <typename T> struct pointersensitiv
    {
      pointersensitiv(T a) {a.foo();}
    };
    
    template<typename T> struct pointersensitiv<T*>
    {
      pointersensitiv(T* a) {a->foo();}
    };
    
    #include<iostream>
    struct nur_zum_test
    {
      void foo() {std::cout << "Foo!\n";}
    };
    
    int main()
    {
      nur_zum_test bar;
      pointersensitiv<nur_zum_test> objekt(bar);
      pointersensitiv<nur_zum_test*> pointer(&bar);
    }
    

  • Mod

    template <typename T>
    T&& deref(T&& v) { return std::forward<T>(v); }
    
    template <typename T>
    T& deref(T* v) { return *v; }
    

    und dann einfach überall, wo a.foo() oder a->foo() auftauchen würde:

    deref(a).foo()
    

    schreiben.



  • @SeppJ
    Buääääääh, Konstruktoren als Funktionen misbrauchen ist mir ein Gräul 🤡



  • camper schrieb:

    template <typename T>
    T&& deref(T&& v) { return std::forward<T>(v); }
    
    template <typename T>
    T& deref(T* v) { return *v; }
    

    und dann einfach überall, wo a.foo() oder a->foo() auftauchen würde:

    deref(a).foo()
    

    schreiben.

    Danke, das war die Lösung. 👍 👍 👍 Die erste Funktion mußte ich aber anpassen:

    template <typename T>
    T& deref(T& v) { return v; }
    
    template <typename T>
    T& deref(T* v) { return *v; }
    

    was sollte denn das T&& deref(T&& v) bedeuten?



  • campers Lösung hat sowohl LValues als auch RValues geschluckt. Deine nimmt nur LValues. Stichwörter: Perfect Forwarding, Reference Collapsing.



  • 314159265358979 schrieb:

    Stichwörter: Perfect Forwarding, Reference Collapsing.

    Und vor allem Anderen Stichwort C++11 und Rvalue-Referenzen. Wenn du das anpassen musstest, kann dein Compiler das wohl noch nicht.



  • pumuckl schrieb:

    314159265358979 schrieb:

    Stichwörter: Perfect Forwarding, Reference Collapsing.

    Und vor allem Anderen Stichwort C++11 und Rvalue-Referenzen. Wenn du das anpassen musstest, kann dein Compiler das wohl noch nicht.

    Ah, gcc version 4.5.2, und die Software soll am Ende auch noch auf VS 2008
    compilieren. Daher habe ich es mit C++11 gar nicht eilig 🙂

    Danke allen für die Hinweise, das Problem ist nun gut gelöst.



  • Beim GCC brauchst du nur beim kompilieren -std=c++0x angeben.


  • Mod

    hustbaer schrieb:

    @SeppJ
    Buääääääh, Konstruktoren als Funktionen misbrauchen ist mir ein Gräul 🤡

    Mir auch. Der Threadersteller hat aber ausdrücklich danach gefragt. Wenn du schnell gewesen wärst, hättest du vor dem edit noch eine Version mit normalen Funktoren gesehen.



  • 314159265358979 schrieb:

    Beim GCC brauchst du nur beim kompilieren -std=c++0x angeben.

    Oder, wie bei mir (wie schon bei unserer Spielwiese festgestellt):
    -std=gnu++0x



  • Zuletzt bearbeitet von Hacker am 16:01:35 17.12.2011, insgesamt 1-mal bearbeitet

    Um uns das mitzuteilen musstest du den Thread nochmals ausgegraben?



  • h4xx02 schrieb:

    Zuletzt bearbeitet von Hacker am 16:01:35 17.12.2011, insgesamt 1-mal bearbeitet

    Um uns das mitzuteilen musstest du den Thread nochmals ausgegraben?

    1. Falsches Deutsch,
    2. Ja. Denn bei mir z.B. klappt das anders nicht, und wenn dich der Thread nervt dann ignorier ihn verdammt nochmal. Dadurch das du (und eig. ich auch) ihn weiter befüllen bleibt er ausgegraben. :xmas1: 😉


Anmelden zum Antworten