2d array (vector*vector) schnell initialisieren



  • happystudent schrieb:

    Ja dieser blöde Komma-Operator 👎
    Verwendet den überhaupt jemand außerhalb von for-Schleifen etc.?

    Arcoth hatte neulich eine nette Verwendung mit SFINAE, afair sizeof(foo,0).

    Könnte man ja vielleicht so machen dass man … extra Klammern angeben muss wenn man den Komma-Operator da verwenden will. Also so:

    mat(i, j); // operator()(int, int)
    mat((i, j)); // operator()(int)
    mat[i, j]; // operator[](int, int)
    mat[(i, j)] // operator[](int)
    

    [/quote]
    Compilerbaue könnten eine Warnung einbauen, wenn man um einen Kommaoperatorausdruck keine Klammern macht.



  • volkard schrieb:

    Nathan schrieb:

    Aber mit der bisherigen Lösung von Proxys geht das auch nicht so richtig, man müsste dazu operator& überladen, so dass man einen entsprechenden Pointer bekommt.
    Alles nicht das Wahre.

    arr.at(y,x) übersetzt.

    Nein, &arr[y] geht nicht wie bei nativen Arrays.

    volkard schrieb:

    happystudent schrieb:

    Ja dieser blöde Komma-Operator 👎
    Verwendet den überhaupt jemand außerhalb von for-Schleifen etc.?

    Arcoth hatte neulich eine nette Verwendung mit SFINAE, afair sizeof(foo,0).

    Nicht nur Arcoth, sizeof(foo, 0) oder decltype(foo, 0) kann man ständig gebrauchen.
    Außerdem gibts da noch das for-each-parameter-pack:

    char dummy[] = {(func(bla), '\0')..., '\0'};
    

  • Mod

    char dummy[] = {(func(bla), '\0')..., '\0'};
    

    Das ist nicht so optimal.

    std::initialier_list<int>{ (func(bla),0)... };
    

    Oder mit

    struct evaluate{ template <typename... A> constexpr evaluate(A&&...) {} };
    
    evaluate{ func(bla)... };
    


  • Nathan schrieb:

    Nein, &arr[y] geht nicht wie bei nativen Arrays.

    Ach, Du willst wirklich auf einem 2D-Array &arr[y] machen. Ok, sehe den Bedarf nicht. Zu viele Implementierungen könnten auch keine sinnvolle getRow(y) anbieten.
    &arr[y] ist nur ein Hack, den man nehmen kann, wenn man das Speicherlayout zufällig genau kennt und es sich nie wieder ändern wird. &arr[0][y] dürfte gehen.



  • Arcoth schrieb:

    char dummy[] = {(func(bla), '\0')..., '\0'};
    

    Das ist nicht so optimal.

    std::initialier_list<int>{ (func(bla),0)... };
    

    Oder mit

    struct evaluate{ template <typename... A> constexpr evaluate(A&&...) {} };
    
    evaluate{ func(bla)... };
    

    Und wenn ich es sequenced haben will?

    volkard schrieb:

    Nathan schrieb:

    Nein, &arr[y] geht nicht wie bei nativen Arrays.

    Ach, Du willst wirklich auf einem 2D-Array &arr[y] machen. Ok, sehe den Bedarf nicht. Zu viele Implementierungen könnten auch keine sinnvolle getRow(y) anbieten.
    &arr[y] ist nur ein Hack, den man nehmen kann, wenn man das Speicherlayout zufällig genau kennt und es sich nie wieder ändern wird. &arr[0][y] dürfte gehen.

    Nee, brauchen würd ich das auch nicht.
    Aber das ist halt der Nachteil, dass arr[x][y], eine expression ist, anstatt wie sonst auch zwei verschiedene.


  • Mod

    Und wenn ich es sequenced haben will?

    Gut geschlafen?



  • Arcoth schrieb:

    Und wenn ich es sequenced haben will?

    Gut geschlafen?

    Function call von evaluate ist definitiv nicht sequenced. Damit meine ich Seiteneffekte von func.
    Und das Proposal dafür ist ein Proposal und afaik nirgendwo implementiert.
    Worauf willst du also hinaus?



  • Nathan schrieb:

    Aber das ist halt der Nachteil, dass arr[x][y], eine expression ist, anstatt wie sonst auch zwei verschiedene.

    Versteh das Problem weiterhin nicht.
    arr.at(y,x) ist ja *ein* Ding, so auch arr[y][x]. arr[y] hat überhaupt keine Bedeutung.

    T& Sparse::at(int y,int x){
    //   return maps[y][x];
    //   return queue[y][x];
    //   return uoMaps[y][x];
       return map[make_pair(y,x)];
       return uoMap[make_pair(y,x)];
    }
    


  • volkard schrieb:

    Nathan schrieb:

    Aber das ist halt der Nachteil, dass arr[x][y], eine expression ist, anstatt wie sonst auch zwei verschiedene.

    Versteh das Problem weiterhin nicht.
    arr.at(y,x) ist ja *ein* Ding, so auch arr[y][x]. arr[y] hat überhaupt keine Bedeutung.

    Hier sollte jetzt eigentlich ein Argument stehen, dass überladene Operatoren ansonsten auch die Semantiken von built-ins haben, aber dann vielen mir , && und || ein, und ich musste dir zustimmen. Das ist kein Problem.


  • Mod

    Function call von evaluate ist definitiv nicht sequenced. Damit meine ich Seiteneffekte von func.

    Ich nehme an, du meinst die Auswertungsreihenfolge der Argumente?

    N3337 [dcl.init.list]/4 schrieb:

    Within the initializer-list of a braced-init-list, the initializer-clauses, including any that result from pack expansions (14.5.3), are evaluated in the order in which they appear. That is, every value computation and side effect associated with a given initializer-clause is sequenced before every value computation and side effect associated with any initializer-clause that follows it in the comma-separated list of the initializer-list.

    x

    Und das Proposal dafür ist ein Proposal und afaik nirgendwo implementiert.

    Welches Proposal?



  • Arcoth schrieb:

    Function call von evaluate ist definitiv nicht sequenced. Damit meine ich Seiteneffekte von func.

    Ich nehme an, du meinst die Auswertungsreihenfolge der Argumente?

    Ja.

    N3337 [dcl.init.list]/4 schrieb:

    Within the initializer-list of a braced-init-list, the initializer-clauses, including any that result from pack expansions (14.5.3), are evaluated in the order in which they appear. That is, every value computation and side effect associated with a given initializer-clause is sequenced before every value computation and side effect associated with any initializer-clause that follows it in the comma-separated list of the initializer-list.

    evaluate{ func(bla)... }; ist AFAIK kein initializer-clause.

    Und das Proposal dafür ist ein Proposal und afaik nirgendwo implementiert.

    Welches Proposal?

    Das Proposal. N4228

    Da sind auch so tolle Sachen wie Modules, operator.(), Ranges, Default comparision, Atomic Smart Pointer, Operator assert, uvm.
    C++17 wird awesome.


  • Mod

    evaluate{ func(bla)... }; ist AFAIK kein initializer-clause.

    evaluate{ func(bla)... } ist selbstverständlich keine initializer-clause, jedenfalls nicht ohne Kontext.
    Aber func(bla)... sind welche. Und zwar für die initializer list mit der die Temporary initialisiert wird.



  • Arcoth schrieb:

    evaluate{ func(bla)... }; ist AFAIK kein initializer-clause.

    evaluate{ func(bla)... } ist selbstverständlich keine initializer-clause, jedenfalls nicht ohne Kontext.
    Aber func(bla)... sind welche. Und zwar für die initializer list mit der die Temporary initialisiert wird.

    Dann hält sich GCC scheinbar nicht daran.
    http://ideone.com/ueQiBN


  • Mod

    Nathan schrieb:

    Dann hält sich GCC scheinbar nicht daran.
    http://ideone.com/ueQiBN

    Ja, das ist ein längst gemeldeter Bug.



  • Arcoth schrieb:

    Nathan schrieb:

    Dann hält sich GCC scheinbar nicht daran.
    http://ideone.com/ueQiBN

    Ja, das ist ein längst gemeldeter Bug.

    Gut zu wissen.
    So lange nutze ich halt char-Arrays.



  • Hm, hätte mir wohl denken können dass das wieder mal nicht so leicht ist wie anfangs gedacht 😃

    Aber dieses N4228 proposal liest sich ja schonmal interessant, danke für den Link. Vielleicht wirds ja dann in C++17 mal was mit matrix[i, j] .



  • happystudent schrieb:

    Vielleicht wirds ja dann in C++17 mal was mit matrix[i, j] .

    Nein, wieso sollte es?
    Das bricht existierenden Code. Und der meiste C+++ Code ist schon geschrieben, die Sprache ist alt und etabliert. Man kann es sich nicht mehr leisten, Code zu brechen.



  • happystudent schrieb:

    Hm, hätte mir wohl denken können dass das wieder mal nicht so leicht ist wie anfangs gedacht 😃

    Aber dieses N4228 proposal liest sich ja schonmal interessant, danke für den Link. Vielleicht wirds ja dann in C++17 mal was mit matrix[i, j] .

    Ok, nach Proxy googlen war zu schwer.

    http://www.c-plusplus.net/forum/57613-full
    http://www.c-plusplus.net/forum/321185-full
    http://www.c-plusplus.net/forum/113709-full



  • Nathan schrieb:

    Nein, wieso sollte es?
    Das bricht existierenden Code. Und der meiste C+++ Code ist schon geschrieben, die Sprache ist alt und etabliert. Man kann es sich nicht mehr leisten, Code zu brechen.

    Es müsste nicht zwingend alten Code brechen. Man könnte es auch so machen dass alter Code bestehen bleibt und nur im Falle eines überladenen operator[](int, ...) die Indizierung anders interpretiert wird:

    struct alter_code {
        int value;
        int &operator[](int i) { return value; }
    };
    
    struct neuer_code {
        int value;
        int &operator[](int i, int j) { return value; }
    };
    
    int main() {
        alter_code ac;
        neuer_code nc;
    
        ac[0, 0] = 1; // operator[](int), da kein operator[] mit mehr als 1 argument überladen
        nc[0, 0] = 2; // operator[](int, int), da operator[] mit > 1 argument vorhanden
    }
    

    Dadurch würde nichts brechen, da alter Code ja keinen operator[] mit mehr als einem überladenen Argument enthalten kann.

    Edit:

    volkard schrieb:

    Ok, nach Proxy googlen war zu schwer.

    http://www.c-plusplus.net/forum/57613-full
    http://www.c-plusplus.net/forum/321185-full
    http://www.c-plusplus.net/forum/113709-full

    Nein, wie bereits (mehrmals) geschrieben geht es um eine indizierung per matrix[i, j] und nicht um eine proxy addressierung mittels matrix[i][j] , da das ja dann keine matrix struktur darstellt sondern eher was wie vector<vector<T>> .



  • happystudent schrieb:

    Nein, wie bereits (mehrmals) geschrieben geht es um eine indizierung per matrix[i, j] und nicht um eine proxy addressierung mittels matrix[i][j] , da das ja dann keine matrix struktur darstellt sondern eher was wie vector<vector<T>> .

    Hab jetzt nicht alles gelesen, aber warum nicht matrix(i, j)? Ist evtl. noch schöner als matrix[i][j].


Anmelden zum Antworten