std::tuple<void> verboten?



  • Suchst du Boost.Optional?

    Und wie camper bereits anmerkte, [tuple.cnstr]/3 - es muss gelten, is_default_constructible<T>::value für alle Typen.


  • Mod

    Ganz nebenbei ist void ein unvollständiger Typ, so dass es in keinem Fall als tuple-Argument verwendet werden darf.



  • stuppi schrieb:

    camper schrieb:

    void ist nicht DefaultConstructible

    Wo ist das Problem? Was nicht passt wird passend gemacht (in diesem Falle DefaultConstructible).

    Die Idee eines Tupels ist es, dass von jedem Typ im Parameter-pack ein Objekt gespeichert wird. Was genau hat deine Vorstellung noch mit einem Tupel zu tun? Was soll das überhaupt bezwecken?

    Consequently, tuples are heterogeneous, fixed-size collections of values.



  • camper schrieb:

    Ganz nebenbei ist void ein unvollständiger Typ, so dass es in keinem Fall als tuple-Argument verwendet werden darf.

    JETZT hab ich dich!

    [temp.arg.type]/2 schrieb:

    A template type argument may be an incomplete type

    Edit: Ach, für Tuple speziell- schade, dann doch nicht.



  • Sone schrieb:

    Die Idee eines Tupels ist es, dass von jedem Typ im Parameter-pack ein Objekt gespeichert wird. Was genau hat deine Vorstellung noch mit einem Tupel zu tun? Was soll das überhaupt bezwecken?

    Die Idee eines Tuples ist es, eine Liste von Typen kompakt zu speichern (EBO).

    Ich könnte das zwar mit

    struct Void {};
    

    erreichen, aber die eine Memberfunktion soll void zurückgeben und nicht Void .



  • stuppi schrieb:

    Sone schrieb:

    Die Idee eines Tupels ist es, dass von jedem Typ im Parameter-pack ein Objekt gespeichert wird. Was genau hat deine Vorstellung noch mit einem Tupel zu tun? Was soll das überhaupt bezwecken?

    Die Idee eines Tuples ist es, eine Liste von Typen kompakt zu speichern (EBO).

    Standard:

    Consequently, tuples are heterogeneous, fixed-size collections of values.

    Values. Values.



  • Sone schrieb:

    camper schrieb:

    Ganz nebenbei ist void ein unvollständiger Typ, so dass es in keinem Fall als tuple-Argument verwendet werden darf.

    JETZT hab ich dich!

    [temp.arg.type]/2 schrieb:

    A template type argument may be an incomplete type

    Sone vs camper
    1 zu 42
    0 zu 42

    ----
    stuppie, was willste erreichen?
    Memberfunktionen? Rückgabe?

    Willst du vielleicht variadic templates oder typelists?



  • Nathan schrieb:

    Sone vs camper
    1 zu 42

    Ne, kannst meinen Punkt wieder weg machen, er hatte schon Recht 😞 . Tuple speichert Werte, und void ist kein vollständiger Typ, daher...



  • Nathan schrieb:

    Sone vs camper
    1 zu 42

    Ne, er hat sich gerade korrigiert.
    0 zu 43.



  • Irgendwann sagt camper was falsches. Irgendwann. Wenn nicht morgen, dann vielleicht in zehn Jahren. Ich werde warten. Er ist auch nur ein Mensch. 😡

    Die Idee eines Tuples ist es, eine Liste von Typen kompakt zu speichern (EBO).

    Das ist hingegen irgendwie die Idee von variadic templates' template parameter packs.



  • Nathan schrieb:

    stuppie, was willste erreichen?
    Memberfunktionen? Rückgabe?

    Willst du vielleicht variadic templates oder typelists?

    Macht in diesem abstrakten Beispiel vielleicht wenig Sinn, aber ich hätte gerne so etwas:

    template <typename T, typename Opt=void>
    struct klassemitoptionalemparameter {
      std::tuple<T, Opt> werte;
    
      Opt gibOptionalenWert() { return std::get<1>(werte); }
    };
    

    Da wäre tuple<void> halt praktisch gewesen.


  • Mod

    n3337 schrieb:

    17.6.4.8/2
    [...]In particular, the effects are undefined in the following cases:
    — if an incomplete type (3.9) is used as a template argument when instantiating a template component, unless specifically allowed for that component.

    Eine entsprechende Ausnahme für tuple existiert nicht.
    Genau genommen stimmt meine Aussage also nicht: Solange das tuple nicht instantiiert wird, kann void verwendet werden. Das dürfte allerdings kaum von irgendeinem Nutzen sein.


  • Mod

    Sone schrieb:

    Irgendwann sagt camper was falsches. Irgendwann. Wenn nicht morgen, dann vielleicht in zehn Jahren. Ich werde warten. Er ist auch nur ein Mensch. 😡

    Hättest mich im C Forum erwischen können (ok, das war eine halbe Unwahrheit).



  • camper schrieb:

    n3337 schrieb:

    17.6.4.28/2
    [...]In particular, the effects are undefined in the following cases:
    — if an incomplete type (3.9) is used as a template argument when instantiating a template component, unless specifically allowed for that component.

    Eine entsprechende Ausnahme für tuple existiert nicht.
    Genau genommen stimmt meine Aussage also nicht: Solange das tuple nicht instantiiert wird, kann void verwendet werden. Das dürfte allerdings kaum von irgendeinem Nutzen sein.

    Dir ist eine 2 in die Paragraphenangabe gerutscht (17.6.4.8).
    Wusste ich übrigens nicht - gut zu wissen 👍

    camper schrieb:

    Sone schrieb:

    Irgendwann sagt camper was falsches. Irgendwann. Wenn nicht morgen, dann vielleicht in zehn Jahren. Ich werde warten. Er ist auch nur ein Mensch. 😡

    Hättest mich im C Forum erwischen können (ok, das war eine halbe Unwahrheit).

    Von C hab ich nun mal überhaupt keine Ahnung. 😃



  • Sone, schäm dich!



  • Mal theoretisch betrachtet (Stichwort algebraischer Typ) repräsentiert ein Tupel einen Produkt-Typen. Und void ist quasi der 0-Typ, weswegen das ganze Produkt 0 wäre.
    Oder anders gesagt: da man kein Objekt von Typ void anlegen kann, könnte man nie ein solches Tupel anlegen, weil man für den void -Teil nichts hätte. Tupel mit void machen somit keinen Sinn, man könnte gleich void nehmen.

    stuppi schrieb:

    abstrakten Beispiel vielleicht wenig Sinn, aber ich hätte gerne so etwas:

    template <typename T, typename Opt=void>
    struct klassemitoptionalemparameter {
      std::tuple<T, Opt> werte;
    
      Opt gibOptionalenWert() { return std::get<1>(werte); }
    };
    

    Was du hier willst, ist ein Typ, der keine inheränten Informationen besitzt. Das ist algebraisch aber nicht der 0-Typ, sondern der 1-Typ, von dem es genau ein mögliches Objekt gibt (womit ich nichts gewonnen habe, wenn ich ein Objekt dieses Typen bekomme, ich weiß ja sowieso, welches es ist).
    In C++ kann man einen solchen Typen repräsentieren durch struct unit {}; , oder auch std::tuple<> .
    Wenn wir uns nun erinnern, dass Tupel Produkttypen sind, haben wir bei einem Tupel mit einem solchen Typen als Element eine 1 im Produkt, die den Wert nicht ändert, das Tupel hat also noch genau denselben Informationsgehalt. Und dass wir keine zusätzlichen Informationen reinbekommen, ist genau das hier Gewünschte.



  • stuppi schrieb:

    Gibt es eigentlich einen guten Grund, weshalb mir mein Compiler bei

    std::tuple<int, void> t;
    

    mit einer über 80 Zeilen langen Fehlermeldung abschmiert?

    Gibt es eigentlich einen Grund, warum man tuple<int,void> benutzen wollen würde? Warum steht da void drin? Wozu soll das gut sein?

    stuppi schrieb:

    Rein technisch müsste tuple<void> doch machbar sein.

    Ich verstehe den Sinn nicht/was dabei rauskommen soll.

    stuppi schrieb:

    Semantisch hätte ich es gerade eben gebraucht um meiner Klasse einen optionalen Member zu spendieren;

    Verwechselst du tuple<int,void> mit boost::optional<int> ?

    stuppi schrieb:

    aber mich würden dennoch die Gründe gegen tuple<void> interessieren.

    Warum hat ein Kreis eigentlich nicht endlich viele Ecken?
    Kann man nicht auch einen Kreis mit endlich vielen Ecken bauen?
    Sollte doch technisch machbar sein.



  • krümelkacker schrieb:

    stuppi schrieb:

    Rein technisch müsste tuple<void> doch machbar sein.

    Ich verstehe den Sinn nicht/was dabei rauskommen soll.

    Ich könnte mir vorstellen, daß man eine Datenstruktur baut, die tuple<A,B> nach A sortiert/gehasht verwaltet und drumherum zwei Wrapper, mit tuple<A,B> ist es eine map, mit tuple<A,void> nur eine set.



  • Ah, ok.

    Statt void könnte man ja mal tuple_element<0,decltype(tie(ignore))>::type probieren.


Anmelden zum Antworten