Soweit der aktuelle Stand.
Nervig finde ich erstens, dass man die template-Parameter bei dieser
Version explizit angeben muss (und damit Fehler machen kann) und
zweitens, dass der Benutzer 1 Array (bzw. eine Initializer list, aber
die sieht ja aus wie ein Array) angibt, obwohl es ja eine 2D-Struktur
ist. Ich finde, man sollte im Code sehen, wie groß das Grid ist.
Ich würde nun gerne einen Konstruktor schreiben, der das erlaubt:
1
grid{{1,2},{3,4},{5,6}};
2
// bzw. optisch ansprechender
3
grid{
4
{1,2},
5
{3,4},
6
{5,6}
7
};
8
// Grid: 3x2 [[1,2],[3,4],[5,6]]
9
// Template parameter automatisch erkannt
Schön wäre es außerdem, wenn das Programm nicht kompiliert, wenn die
inneren Arrays nicht gleich lang sind.
Wichtig ist aber, dass alles constexpr ist, also zum Beispiel mittels
static_assert() überprüfbar.
Gibt es so ein Konstrukt im aktuellen C++?
Mit freundlichen Grüßen,
nga
Man kann zwar initializer_list verschachteln, allerdings sehe ich gerade
keine Möglichkeit die Länge einer inilializer_list als constexpr zu
ermitteln, wenn die initializer_list als Funktionsparameter übergeben
wird, da sie in diesem Kontext wieder nicht mehr constexpr ist.
Deswegen sehe ich erstmal nur die beiden Möglichkeiten oben. Einmal mit
einer Factory und op() oder einem Helper-Typ R.
Hallo Wilhelm M.,
danke für deine Beiträge.
An die Möglichkeit einer Factory habe ich gar nicht gedacht, die Idee
ist gut.
Der Helper-Typ ist zwar von der Idee auch nicht schlecht und vmtl.
einfach zu implementieren, aber sagt mir ehrlich gesagt nicht so zu.
Wilhelm M. schrieb:> Man kann auf den helper make_grid() auch verzichten, wenn man ein DGuide> einsetzt:
1
constexprautog=grid(1,2)(3,4)(5,6);
> Passt das für Dich?
Diese Möglichkeit finde ich sehr schön, aber ich muss jetzt (mglw. blöd)
fragen: Was ist ein DGuide? Ich habe diesen Begriff noch nie gehört.
Es wäre nett, wenn du entweder Informationen verlinken könntest oder
eine Beispiel-Signatur des Konstruktor schreiben würdest (irgendwie
komme ich gerade nicht drauf, wie man das einfach Implementieren kann).
Grüße,
nga
>> Passt das für Dich?>> Diese Möglichkeit finde ich sehr schön, aber ich muss jetzt (mglw. blöd)> fragen: Was ist ein DGuide? Ich habe diesen Begriff noch nie gehört.
Damit ist ein user-defined deduction-guide gemeint. Beispiel kommt
gleich ...
Wie schon beschrieben, sind std::initializer_list's hier nur wenig
geeignet, da sie in einem constexpr-Kontext nur schlecht funktionieren.
Es gab mal einen Entwurf, die Länge statisch als member-typ zur
Verfügung zu stellen ...
Mit concepts können man die überladenen ctor'en etwas besser gestalten.
Hallo,
danke für das Beispiel!
Ich werde allerdings wohl etwas brauchen, bis ichs komplett verstanden
habe. Mir sind das irgendwie zu viele "..." :-)
Grüße und nochmals vielen Dank,
nga
Hallo,
ich muss mich nochmal als unfähig/unwissend outen... (mach ich nicht
gerne :-) ).
Betreffend dieses Parts:
Wilhelm M. schrieb:> template<typename... VV>> constexpr auto operator()(VV... rv) {> static_assert(sizeof...(VV) == columns, "wrong number of values> to form a complete row");> // static_assert((std::is_same_v<ItemType, VV> && ...), "use> always the same type");> auto n = [&]<auto... RR>(std::index_sequence<RR...>) { // C++20,> refactor to function-template if C++17> std::array<ItemType, columns> nextRow{ItemType(rv)...};> grid<ItemType, rows + 1, columns> n{(*this)[RR]...,> nextRow};> return n;> }(std::make_index_sequence<rows>{});> return n;> }
Ich möchte das ganze erst mal mit der aktuellsten verabschiedeten
Version der Sprache machen, also C++17 (ohne GNU extensions o.Ä.).
Also kann ich das Lambda Template so in der Art (wie du netterweise
geschrieben hast) nicht verwenden -.-
Ich habe mich mal hingesetzt und versucht das ganze mittels
template-Funktionen nachzubilden (Compiler Explorer):
https://godbolt.org/g/ZBvVES
Leider kenne ich mich mit TMP im Prinzip gar nicht aus und ich kann
weder mit der GCC-Fehlermeldung, noch mit der von clang etwas
anfangen...
GCC:
note: in instantiation of function template specialization 'grid<double, 1, 2>::operator()<int, int>' requested here
2
note: candidate template ignored: could not match 'integer_sequence<unsigned long, RR...>' against 'int'
(Genaueres alles im Compiler Explorer zu sehen)
Ich denke, dass ich einen trivialen Fehler
Es wäre furchbar nett, wenn du mir noch einmal auf die Sprünge helfen
könntest, oder entsprechende Literatur zu aktueller C++ TMP empfehlen
könntest.
Grüße,
nga