C++0x - late_check


  • Administrator

    Sebastian Pizer schrieb:

    Könnte durchaus sein. Man geht eh nicht davon aus, dass Otto Normalbürger, Konzepte schreibt, höchstens Konzept-Maps, damit er einen Algorithmus A aus Bibliothek B auf seine Datenstruktor D loslassen kann.

    Die Frage ist nur, wieviele Bibliotheken Konzepte haben werden.

    Sebastian Pizer schrieb:

    Eine "konzeptisierte" Standardbibliothek ist schonmal nicht schlecht. Leider hat man mit diesem Sprachfeature wenig Erfahrung bisher sammeln können und es gibt auch keinen experimentellen Compiler, der auf dem aktuellen Stand ist und nicht gleich abkackt, wenn man ihm mal ein etwas komplizierteres Beispiel zu fressen gibt.

    Und deshalb sage ich jetzt auch mal nichts weiteres dazu. Ich lasse mich überraschen, wie es sein wird, damit eine Templatebibliothek zu schreiben.

    Allerdings wie hustbaer frage ich mich da auch noch etwas:

    Sebastian Pizer schrieb:

    ... und sich Elementfunktionen auch nicht per concept maps umliegen lassen ...

    Meinst du mit Elementfunktionen Memberfunktionen? Wenn ich den letzten Standard Draft n2914 richtig verstehe, soll dies allerdings möglich sein.

    concept MyConcept<typename T>
    {
      void T::foo() const;
    }
    
    class MyClass
    {
    public:
      void bar() const;
    };
    
    concept_map<MyClass>
    {
      void MyClass::foo() const { bar(); }
    }
    
    template<typename T>
      requires MyConcept<T>
    void foobar(T const& obj)
    {
      obj.foo();
    }
    

    Allerdings habe ich zum Teil sowieso etwas Mühe mit den Formulierungen. Oder hast du womöglich sogar etwas anderes damit gemeint?

    Grüssli



  • hustbaer schrieb:

    und sich Elementfunktionen auch nicht per concept maps umbiegen lassen

    Huch? Wozu sollen die dann überhaupt gut sein???

    Eine Konzeptdefinition besteht aus bis zu 3 Dingen:
    - assoziierte Anforderungen (associated requirements)
    - assoziierte Typen (associated types)
    - assoziierte Funktionen (associated functions)

    Mit concept maps kannst Du sagen, dass ein Typ (oder mehere) das Konzept modellieren:

    concept Foo<typename T> {}
      concept_map Foo<int> {}
    

    Hier gibt es keine Anforderungen. Trotzdem modelliert nur der Typ int das Konzept, weil's keine andere concept_map gibt.

    Concept maps sind aber auch dazu da, zu sagen, wie ein Typ das Konzept modelliert. Du musst dabei alle Anforderungen erfüllen. Beispiel:

    auto concept Foo<typename T> {
        typename blah;        // assoziierter Typ
        typename lola;        // assoziierter Typ
        blah blupp(T);        // assoziierte Funktion
      }
    
      template<typename T> requires Regular<T> && Foo<T>
      void xxx(T x) {
        typedef Foo<T>::lola zzz;
      }
    
      struct meintyp {};
      int blupp(meintyp const&);
    
      int g() {
        xxx(meintyp()); // Klappt nicht!
      }
    

    Hier versucht der Compiler eine concept map für Foo<meintyp> zu finden. Da ich eine solche nicht angegeben habe und Foo ein auto concept ist, versucht der Compiler die concept map automatisch zu generieren. Dazu werden u.a. auch Defaults beachtet (Du kannst Default-Funktionen und -Typen in concepts definieren). In diesem Fall findet der Compiler eine Funktion blupp im assoziierten Namensraum der Klasse meintyp , welche auf Foo<meintyp>::blupp passt -- auch wenn sie eine Referenz auf const als Parameter erwartet. Der Compiler kann sogar den assoziierten Typen blah herleiten ( Foo<meintyp>::blah ist ein int , da blupp(meintyp) ein int zurückgibt). Aber der Compiler weiß nicht, was der Typ lola sein soll. Deswegen braucht man hier eine concept map:

    concept_map Foo<meintyo> {
      typedef bool lola;
    }
    

    Gruß,
    SP



  • Dravere schrieb:

    Allerdings wie hustbaer frage ich mich da auch noch etwas:

    Sebastian Pizer schrieb:

    ... und sich Elementfunktionen auch nicht per concept maps umliegen lassen ...

    Meinst du mit Elementfunktionen Memberfunktionen? Wenn ich den letzten Standard Draft n2914 richtig verstehe, soll dies allerdings möglich sein.

    Wenn ich mich richtig erinnere, benutzt das Buch "Die C++ Programmiersprache" (deutsche Übersetzung der TC++PL special edition) den Begriff Elementfunktion für Funktionen, die im englischen Original "member functions" heißen. Das kann ich aber gerade nicht nachgucken, weil das Buch im Büro liegt und ich jetzt zu Hause sitze.

    Dass man Elementfunktionen jetzt auch umbiegen kann, ist mir neu. Ich dachte, da gäb es Probleme mit der Namensauflösung. Lass mich mal grad in N2914 reingucken ...

    Gruß,
    SP


  • Administrator

    Sebastian Pizer schrieb:

    Wenn ich mich richtig erinnere, benutzt das Buch "Die C++ Programmiersprache" (deutsche Übersetzung der TC++PL special edition) den Begriff Elementfunktion für Funktionen, die im englischen Original "member functions" heißen. Das kann ich aber gerade nicht nachgucken, weil das Buch im Büro liegt und ich jetzt zu Hause sitze.

    Das konnte ich dafür gerade nachschauen. Die verwenden dort tatsächlich Elementfunktion. Wahrscheinlich aus der genialen Idee der 1:1 Übersetzung. Aber gut, wie soll man sie sonst auf Deutsch nennen. Member ist ja kein deutsches Wort 🙂

    Sebastian Pizer schrieb:

    Dass man Elementfunktionen jetzt auch umbiegen kann, ist mir neu. Ich dachte, da gäb es Probleme mit der Namensauflösung. Lass mich mal grad in N2914 reingucken ...

    Bereich 14.10, bzw. 14.10.2.1
    Ich bin wirklich gespannt, ob ich das Zeug richtig verstanden habe, denn ich hatte sehr viel Mühe, aus dem Text schlau zu werden.

    Grüssli



  • Sebastian Pizer schrieb:

    Aber der Compiler weiß nicht, was der Typ lola sein soll. Deswegen braucht man hier eine concept map:

    concept_map Foo<meintyo> {
      typedef bool lola;
    }
    

    Alternativ kann man eine Vorgabe machen:

    concept Bar<typename T> {
      typename value_type = typename T::value_type;
      // .....
    }
    

    was für eingebeute Typen natürlich nicht funktionieren kann. Dann braucht man wieder concept_map s:

    template<typename T>
    concept_map Bar<T*> {
      typedef T value_type;
      // .....
    }
    

    Gruß,
    SP



  • Dravere schrieb:

    Sebastian Pizer schrieb:

    Dass man Elementfunktionen jetzt auch umbiegen kann, ist mir neu. Ich dachte, da gäb es Probleme mit der Namensauflösung. Lass mich mal grad in N2914 reingucken ...

    Bereich 14.10, bzw. 14.10.2.1
    Ich bin wirklich gespannt, ob ich das Zeug richtig verstanden habe, denn ich hatte sehr viel Mühe, aus dem Text schlau zu werden.

    Ich kann auch im aktuellen Entwurf keine Syntax für das Definieren von Pseudo-Elementfunktionen in concept map s finden. Es gibt auch keine Beispiele, in denen soetwas gemacht wird. Das, was Du innerhalb einer concept map schreibst, ist ganz normaler Code: typedef s und Funktionen, die die Konzept-Anforderungen erfüllen müssen.

    Gruß,
    SP


  • Administrator

    Sebastian Pizer schrieb:

    Ich kann auch im aktuellen Entwurf keine Syntax für das Definieren von Pseudo-Elementfunktionen in concept map s finden. Es gibt auch keine Beispiele, in denen soetwas gemacht wird. Das, was Du innerhalb einer concept map schreibst, ist ganz normaler Code: typedef s und Funktionen, die die Konzept-Anforderungen erfüllen müssen.

    Es hat keine Beispiele, aber einen Text, den ich so verstehe.
    Kapitel 14.10.2.1 Associated Function Definitions
    Abschnitt 4

    ...
    The expression E is defined differently depending on the associated function and the concept map definition. Let parm1, parm2, ..., parmN be the parameters of f (after substitution of the concept map arguments) and parm1', parm2', ..., parmN' be expressions, where each parmi' is an id-expression naming parmi. If the declared type of parmi is an lvalue reference type, then parmi' is treated as an lvalue, otherwise, parmi' is treated as an rvalue.

    For an associated member function (or member function template) in a type X (after substitution of the concept map arguments into the associated member function or member function template), let x be an object of type cv X, where cv are the cv-qualifiers on the associated member function (or member function template). If the requirement has no ref-qualifier or if its ref-qualifier is &, x is an lvalue; otherwise, x is an rvalue.

    The expression E is defined as follows:
    — If f is an associated non-member function or function template and the concept map contains one or more function or function template definitions with the same name as f, E is f(parm1', parm2', ..., parmN'), and the overload set of entities f consists of the definitions of f in the concept map. [Note: Unqualified lookup 3.4.1 and argument dependent lookup 3.4.2 are suppressed. —end note ].
    — Otherwise, if f is a non-static associated member function and the concept map contains one or more member function or member function template definitions in the type X and with the same name as f, E is x.f(parm1', parm2', ..., parmN'), where name lookup of x.f refers to the definitions of X::f in the concept map.
    ...

    Schau ruhig noch die Bereich davor und danach an. Wie gesagt, womöglich verstehe ich es einfach nur falsch. Aber wenn nicht, dann bedeuetet der hervorgehobene Teil, dass in einer concept_map nach einer Definition einer Memberfunktion gesucht wird.

    Grüssli



  • Wie gesagt, es ist dazu keine Syntax definiert. Die Formulierungen in 14.10.2.1/3-4 finde ich auch etwas komisch. Ich schätze mal, dass mit "definitions of X::f in the concept map" die "requirement members" gemeint sind.

    N2914, 14.10.2/3-4:

    A concept map may contain two kinds of members: requirement members and members that satisfy requirements. The latter may be explicitly declared within the concept map, explicitly declared within a concept map for a more refined concept, or generated implicitly from a default implementation from the concept or one of its more refined concepts.

    Each requirement member represents an entity (a single associated functio (14.10.1.1), associated type or associated class template (14.10.1.2) in the corresponding concept that must be satisfied as described below. The set of requirement members is the set of associated functions, associated types and associated class templates from the concept after substitution of the concept’s template parameters with the corresponding template arguments. [ Note: There is no way to explicitly declare a requirement member. — end note ]

    Gruß,
    SP



  • Sebastian Pizer schrieb:

    Wie gesagt, es ist dazu keine Syntax definiert. Die Formulierungen in 14.10.2.1/3-4 finde ich auch etwas komisch. Ich schätze mal, dass mit "definitions of X::f in the concept map" die "requirement members" gemeint sind.

    Nee, das macht auch keinen Sinn. 😕

    Gruß,
    SP



  • hustbaer schrieb:

    und sich Elementfunktionen auch nicht per concept maps umliegen lassen

    Huch? Wozu sollen die dann überhaupt gut sein???

    Elementfunktionen sind nicht die einzigen Funktionen, die zu einer Schnittstelle einer Klasse gehören. Das sind auch alle Funktionen, die im selben Namensraum definiert wurden und die Klasse in den Parametern "erwähnt".

    Gute Artikel dazu sind die hier:
    What's in a Class? -- Herb Sutter (1998)
    Namespaces & Interface Principle -- Herb Sutter (1999)

    Ich bin mir zu 100% sicher, dass man in concept maps keine Elementfunktion definieren kann. Diskussionen gab es dazu schon öfters (bin aber gerade zu faul, die Threads rauszusuchen, siehe comp.std.c++).

    Gruß,
    SP


  • Administrator

    Sebastian Pizer schrieb:

    Ich bin mir zu 100% sicher, dass man in concept maps keine Elementfunktion definieren kann. Diskussionen gab es dazu schon öfters (bin aber gerade zu faul, die Threads rauszusuchen, siehe comp.std.c++).

    In einem Thread aus dem Jahr 2007 wurde es ganz klar verneint:
    http://groups.google.de/group/comp.std.c++/browse_thread/thread/c0e76cd89d837dae/b70460b055918af5

    Aus einem Thread im Jahr 2009 wurde ich nicht mehr ganz schlau. Aber so wie sich das liest, haben auch andere Leute Probleme mit der Erklärung 😃
    http://groups.google.de/group/comp.std.c++/browse_thread/thread/c6a53c8e77f1937b/b879bd39eb75aeeb

    Ein schönes Fundstück ist dies:

    Scott Meyers schrieb:

    Oh, this is going to be fun to explain to people....

    Thanks for the explanation, which, upon third reading, actually began to
    make sense 🙂

    Scott

    -> http://groups.google.de/group/comp.std.c++/browse_thread/thread/6e1b78a38f7c16ef/c746c77e95e34eb7

    Ich glaub, dass ich einfach mal noch warten werde, bis der Standard rauskommt. Dann lasse ich mir dass von jemandem erklären. Vielleicht kann dass ja Scott Meyers in einem guten Buch tun 😃

    Grüssli



  • Dravere schrieb:

    Ein schönes Fundstück ist dies:

    Scott Meyers schrieb:

    Oh, this is going to be fun to explain to people....
    Thanks for the explanation, which, upon third reading, actually began to
    make sense 🙂

    -> http://groups.google.de/group/comp.std.c++/browse_thread/thread/6e1b78a38f7c16ef/c746c77e95e34eb7

    Ja, Scott Meyers meldet sich da öfters mal mit Teils super Beiträgen zu Wort. Es ist noch nicht so lange her, wo er zum Thema Rvalue-Referenzen und "perfect forwarding" mit diskutiert hat. Zuletzt hatte ich mich mit ihm zum Thema "Argument passing semantics for threads" gestritten -- und "gestritten" ist nicht übertrieben. Im Prinzip haben wir uns über knapp 50 Posts im Kreis gedreht. 😞

    Es ist aber beruhigend, dass auch Leute, wie Scott Meyers Schwierigkeiten haben, Rvalue-Referenzen zu verstehen. Dann muss ich mir auch nicht mehr so doof vorkommen, wenn ich daran denke, wie lange ich gebraucht habe, das alles zu raffen. 🕶

    Gruß,
    SP


Anmelden zum Antworten