facebook releases Folly, an open source C++ library





  • Wow, das sieht auf den ersten Blick ziemlich vielversprechend aus. Laut Header-Kommentaren hat da zum großen Teil Andrei Alexandrescu seine Finger mit im Spiel gehabt. Nur warum veröffentlicht Facebook das?



  • Bloops schrieb:

    Wow, das sieht auf den ersten Blick ziemlich vielversprechend aus. Laut Header-Kommentaren hat da zum großen Teil Andrei Alexandrescu seine Finger mit im Spiel gehabt. Nur warum veröffentlicht Facebook das?

    Dann haben sie ihm bestimmt genötigt 🤡



  • browse da gerade so drüber und bin über folgendes gestoplert:

    template <typename... Types>
    class DiscriminatedPtr {
    
      ...
    
      /**
       * Get a pointer to the object that this DiscriminatedPtr points to, if it is
       * of type T.  Fails at compile time if T is not a valid type (listed in
       * Types), and returns nullptr if this DiscriminatedPtr is empty or points to
       * an object of a different type.
       */
      template <typename T>
      T* get_nothrow() noexcept ...
    
      template <typename T>
      const T* get_nothrow() const noexcept ...
    
      /**
       * Get a pointer to the object that this DiscriminatedPtr points to, if it is
       * of type T.  Fails at compile time if T is not a valid type (listed in
       * Types), and throws std::invalid_argument if this DiscriminatedPtr is empty
       * or points to an object of a different type.
       */
      template <typename T>
      T* get() ...
    
      template <typename T>
      const T* get() const ...
    
      ...
    
    };
    

    Da hat scheinbar jemand "const" nicht ganz verstanden; denn "const T*" bringt absolut gar nichts, da man den Zeiger ja kopieren kann:

    void foo(DiscriminatedPtr<int,double> const& x)
    {
      x.get_nothrow<int>(); // --> const int*
      auto y = x;
      y.get_nothrow<int>(); // --> int*
    }
    

    Ich hätte das so gebaut:

    template <typename... Types>
    class DiscriminatedPtr {
    
      ...
    
      template <typename T>
      T* get_nothrow() const noexcept ...
    
      template <typename T>
      T* get() const ...
    
      ...
    
    };
    

    Also mit const-Methoden, die T* zurück geben. Das passt dann auch zum Verhalten von rohen Zeigern.



  • It's open source fix it!



  • krümelkacker, du hast da was falsch verstanden in Bezug auf const und Zeiger.

    const T * foo; // foo ist ein Zeiger auf ein konstantes T
    T const * foo; // selbiges
    
    T * const foo; // konstanter Zeiger auf variables foo
    
    const T * const foo; // konstanter Zeiger auf konstantes foo
    T const * const foo; // selbiges
    

    Du siehst also, dass die Methoden keine konstanten Zeiger zurückgeben,
    sondern normale Zeiger auf konstante Objekte, und da bekommt man das const in C++ nur mit const_cast oder C-Style-Cast weg.



  • krümelkacker schrieb:

    Da hat scheinbar jemand "const" nicht ganz verstanden; denn "const T*" bringt absolut gar nichts, da man den Zeiger ja kopieren kann:

    Kannst Du das ein wenig genauer erläutern. Ich scheine "const" auch nicht ganz verstanden zu haben 😕 .

    Ein "const T*" ist ein Zeiger auf ein Objekt, welches ich nicht modifizieren kann. Über den "const T*" kann ich nur Methoden aufrufen, die const sind. Ein "const T*" kann ich zwar kopieren, aber nicht auf einen "T*" sondern nur auf einen anderen "const T*". Da gilt die Restriktion genau so.

    In Deinem Beispiel ist x eine konstante Referenz. Eine konstante Referenz kann ich auch nur einer Konstanten Referenz zuweisen. Also ist y in der Zeile "auto y = x" auch eine konstante Referenz.



  • krümelkacker schrieb:

    Da hat scheinbar jemand "const" nicht ganz verstanden; denn "const T*" bringt absolut gar nichts, da man den Zeiger ja kopieren kann.

    Jein, wenn ich eine konstanten Smartpointer bekommen, sollte ich davon auch nur einen konstenten raw-Pointer ein Raw-Pointer auf Konst bekommen.



  • DrakoXP schrieb:

    krümelkacker, du hast da was falsch verstanden in Bezug auf const und Zeiger.

    Nein, habe ich nicht.

    tntnet schrieb:

    Kannst Du das ein wenig genauer erläutern. Ich scheine "const" auch nicht ganz verstanden zu haben 😕 .
    [...]
    In Deinem Beispiel ist x eine konstante Referenz. Eine konstante Referenz kann ich auch nur einer Konstanten Referenz zuweisen. Also ist y in der Zeile "auto y = x" auch eine konstante Referenz.

    x ist ein Lvalue vom Typ const DiscriminatedPtr<int,double>
    y ist ein Lvalue vom Typ DiscriminatedPtr<int,double>

    Zeus schrieb:

    Jein, wenn ich eine konstanten Smartpointer bekommen, sollte ich davon auch nur einen konstenten raw-Pointer bekommen - semantisch richtig, dass C++ die Kopie auf ein nicht-konstenten Pointer erlaubt, ist ein Kritik von der D Community 😉

    Das ist Unsinn.

    Leute, leute! Ihr enttäuscht mich! Das kann doch nicht so schwer sein! Der Sinn von DiscrimiatedPtr<...> ist ein etwas typsicherer void-Zeiger. Er kann auf Objekte verschiedener Typen zeigen und weiß sogar noch, um welchen Typ es sich da handelt. Da sollte man erwarten, dass sich DiscriminatedPtr<int> ähnlich wie int* verhält. Stattdessen gibt mir ein konstanter Discriminated<int> einen const int* zurück. Das ist einfach Schwachsinn!

    Das Verhalten eines normalen rohen Zeigers ist äquivalent zu:

    template<class T>
    class pointer
    {
    public:
      ...
      T& operator*() const {return *ptr;}
      T* operator->() const {return ptr;}
      ...
    private:
      T* ptr;
    };
    

    Das heißt: Unabhängig davon, ob ich auf den Zeiger const oder non-const-Zugriff habe, bekomme ich ein T& beim dereferenzieren! Ja, das ist wirklich so:

    #include <iostream>
    using namespace std;
    void wasbinich(const int&) {cout<<"const int\n";}
    void wasbinich(      int&) {cout<<"      int\n";}
    int main()
    {
      int i = 42;
      int*       p = &i;
      int* const q = &i;
      wasbinich(*p);
      wasbinich(*q);
    }
    

    Ausgabe:

    int
          int
    

    Tada!

    Bitte Hirn einschalten und dann posten.



  • Ja, die const-Overloads im DiscriminatedPtr sind reichlich sinnlos.
    "Korrekt" ist mMn. was shared_ptr macht.

    D.h. ein DiscriminatedPtr<int, double> müsste implizit zu DiscriminatedPtr<int const, double const> konvertierbar sein, aber nicht umgekehrt.
    Und der DiscriminatedPtr<int const, double const> darf dann natürlich auch nur int const* bzw. double const* hergeben.



  • Findet ihr?

    #include <iostream>
    using namespace std;
    
    class fun
    {
    public:
    	void print() {
    		cout << "Side-effect";
    	}
    
    	void print() const {
    		cout << "Side-effect free";
    	}
    };
    
    template<typename T> class pointer
    {
    public:
    	pointer(T* ptr) : ptr(ptr) {
    
    	}
    	T* get() {
    		return ptr;
    	}
    
    	T* get() const {
    		return ptr;
    	}
    private:
    	T* ptr;
    };
    
    void invoke(const pointer<fun>& ptr) {
    	ptr.get()->print();
    }
    
    int main()
    {
    	fun* f = new fun();
        pointer<fun> p = f;
        invoke(p);
    }
    


  • Was it der Sinn deines Beitrags? Was willst du uns damit sagen? Dass du nicht verstanden hast was wir meinen? 🤡



  • hustbaer schrieb:

    Dass du nicht verstanden hast was wir meinen? 🤡

    Höchstwahrscheinlich 🙄



  • Naja komm dein Beispiel ist Quatsch, und das solltest du auch wissen wenn du den letzten Beitrag von kk gelesen hättest.

    Klar geht das so wie du es zeigst, aber es bleibt trotzdem Quatsch, und es bietet vor allen keinerlei Sicherheit.

    void invoke(const pointer<fun>& ptr) {
        pointer<fun> p2 = ptr;
        p2.get()->print();
    }
    

    EDIT: OK, du zeigst die Variante wo get immer "T*" und nie "T const"* zurück gibt. Also geht es dort nicht, aber es geht eben so sowieso nicht. /EDIT

    Achja, hier die sinnvolle, funktionierende Variante:

    int main() 
    { 
         fun* f = new fun(); 
         pointer<fun const> p = f; 
         invoke(p); 
    }
    


  • Bloops schrieb:

    Nur warum veröffentlicht Facebook das?

    Weil sie viel auf Open Source setzen und viele ihrer Bibliotheken Open Source machen wollen. Warum auch nicht, wenn man von der Community gratis Bugfixes und neue Features bekommen kann. FB will wohl noch mehr ihrer Bibliotheken veröffentlichen, das ist nur der Anfang.

    http://herbsutter.com/2012/06/02/facebook-folly-oss-c-libraries/?utm_source=tf&utm_medium=t



  • Ich verstehe zwar grundsätzlich, worauf krümelkacker hinaus will und stimme auch zu, aber stimmt das hier wirklich:

    void foo(DiscriminatedPtr<int,double> const& x)
    {
      x.get_nothrow<int>(); // --> const int*
      auto y = x;
      y.get_nothrow<int>(); // --> int*
    }
    

    😕
    Wieso geht denn hier beim Kopieren die Constqualifizierung des Zeigers verloren?

    Edit: Ach ja. Ich bin ja so doof. Hat sich erledigt.



  • Tachyon schrieb:

    Ich verstehe zwar grundsätzlich, worauf krümelkacker hinaus will, aber stimmt das hier wirklich:

    void foo(DiscriminatedPtr<int,double> const& x)
    {
      x.get_nothrow<int>(); // --> const int*
      auto y = x;
      y.get_nothrow<int>(); // --> int*
    }
    

    😕
    Wieso geht denn hier beim Kopieren die Constqualifizierung des Zeigers verloren?

    const/nonconst-Überladung, analog zu dem hier:

    void bar(std::vector<int> const& v)
    {
      v.begin(); // --> const_iterator
      auto y = v; //std::vector<int>, ohne const!
      y.begin(); // --> iterator
      auto const z = v; //std::vector<int> const
      z.begin(); // --> ah, const_iterator!
    }
    

    😉



  • Ja. Bin inzwischen selbst drauf gekommen. Nachdenken hilft, wie bereits weiter oben geschrieben wurde.



  • hustbaer schrieb:

    Naja komm dein Beispiel ist Quatsch, und das solltest du auch wissen wenn du den letzten Beitrag von kk gelesen hättest.

    Natürlich ist es Quatsch, ich hab ja KK Rat befolgt und den Const-Q. entfernt!



  • Zeus schrieb:

    hustbaer schrieb:

    Naja komm dein Beispiel ist Quatsch, und das solltest du auch wissen wenn du den letzten Beitrag von kk gelesen hättest.

    Natürlich ist es Quatsch, ich hab ja KK Rat befolgt und den Const-Q. entfernt!

    Was daran nix ändert dass der Code Quatsch ist.

    Mit entferntem Const-Qualifizierer sieht man es bloss schneller.
    Mit nicht entferntem Const-Qualifizierer ist es deswegen aber nicht weniger Qutasch.


Anmelden zum Antworten