Portál AbcLinuxu, 4. června 2024 09:32


Dotaz: [c++2a] Aggregate initialization

hermes avatar 4.10.2021 17:47 hermes | skóre: 6 | blog: Elektro | BA
[c++2a] Aggregate initialization
Přečteno: 434×
Odpovědět | Admin
Ahojte, občas používam anemické objekty (alebo čo to je) ako prepravky... (Napríklad keď si robím restové API a deserializujem JSONy, ktoré potom ukladám do DB.) Problém je, že C++ štandard je veľmi striktný, atribúty musím pri inicializácii zadať v rovnakom poradí, ako som ich deklaroval v triede a nemôžem ich vynechať. Prečo to tak je? A dá sa to nejako obísť? Nejakým parametrom compilera (GCC), alebo nejakým iným zápisom? Niečo sa mi marí, že v čistom (novom) C som raz videl aj iný spôsob zápisu (tuším každá propsa spolu s hodnotou bola obalená ešte v jednom páre zložených zátvoriek), ale ten v C++ nefunguje. Má to teda nejaké riešenie?
struct Entity
{
    int prop1;
    int prop2;
    int prop3;
};

auto entity = Entity{ .prop1 = 1, .prop2 = 2, .prop3 = 3 };

Řešení dotazu:


Nástroje: Začni sledovat (0) ?Zašle upozornění na váš email při vložení nového komentáře.

Odpovědi

Řešení 1× (Bhezret)
4.10.2021 18:23 Andrej | skóre: 51 | blog: Republic of Mordor
Rozbalit Rozbalit vše Re: [c++2a] Aggregate initialization
Odpovědět | | Sbalit | Link | Blokovat | Admin

Možná to chce udělat krok zpátky a podrobněji popsat, jaký problém řešíš, a zejména proč je pro řešení toho problému tak důležité proměnlivé pořadí členů ve třídě a proč se nedá najít v C++ taková reprezentace, která to pořadí bude mít „správně“.

Nedá se zkrátka pořadí členů permutovat tak, aby mu obvyklý způsob inicializace odpovídal?

Pokud to nejde a někteří členové nemusí být k dispozici, dá se použít std::optional (pro přímé zapouzdření) nebo std::unique_ptr (pro „zapouzdření“ à la Java)?

Pokud se pořadí některých členů musí fakt libovolně náhodně lišit (proč?), pomohl by třeba std::variant nebo dynamický kontejner nebo kombinace obojího?

Nedá se to rozdělit na víc různých typů? Nepomohla by dědičnost a mít to, co je vždy k dispozici, ve společném rodiči? (Což je opět stejná otázka jako „je možná permutace taková, že…“.)

hermes avatar 4.10.2021 23:31 hermes | skóre: 6 | blog: Elektro | BA
Rozbalit Rozbalit vše Re: [c++2a] Aggregate initialization
Prečo to potrebujem? Je za tým viac dôvodov. Občas to pomôže sprehľadniť kód. V iných jazykoch sú plain objekty mocná zbraň... V JS / TSku sa dajú plain objecty používajú napríklad ako náhrada za pomenované parametre. Ale je za tým aj to vynechávanie. Keby to bolo o niečo málo flexibilnejšie, malo by to viac use cases.
5.10.2021 03:14 Andrej | skóre: 51 | blog: Republic of Mordor
Rozbalit Rozbalit vše Re: [c++2a] Aggregate initialization

Pokud to má být extrémní flexibilita bez ohledu na efektivitu, třeba je to případ pro std::unordered_map<std::string, std::variant<Spousta, Různých, Variant, ...>>. I když, pro ještě větší podobnost JavaScriptu by ten klíč měl být asi std::variant<Nějaké, Skalární, Typy, ...> místo std::string.

Jenže: Proč dělat z C++ JavaScript? Určitě se ten nápad dá v C++ vyjádřit líp a „idiomaticky“. Pokud ne, třeba je lepší to nechat v JavaScriptu.

Gréta avatar 4.10.2021 21:27 Gréta | skóre: 36 | blog: Grétin blogísek | 🇮🇱==❤️ , 🇵🇸==💩 , 🇪🇺==☭
Rozbalit Rozbalit vše Re: [c++2a] Aggregate initialization
Odpovědět | | Sbalit | Link | Blokovat | Admin

co jakoby takle uplně jednoduše :D

struct Entity
{
    int a, b, c;
};

int main()
{
    
    Entity hermes;
    hermes.c=1;
    hermes.b=2;
    hermes.a=3;
    
    return 0;
}
oslavná píseň na pana soudruha generalisima prezidentčíka Petra Pavla Pávka 🎶🫡🦚🎶
hermes avatar 4.10.2021 23:32 hermes | skóre: 6 | blog: Elektro | BA
Rozbalit Rozbalit vše Re: [c++2a] Aggregate initialization
No len nevýhoda je, že to už neni inicializácia, ale priraďovanie, veľakrát je to skoro jedno, ale keby tam bol napr. const tak by to nefungovalo. Okrem toho v niektorých situáciách sa snažím preferovať immutablitu a teda inicializáciu pred priraďovaním.
5.10.2021 03:03 Andrej | skóre: 51 | blog: Republic of Mordor
Rozbalit Rozbalit vše Re: [c++2a] Aggregate initialization

Ale const tam můžeš mít taky, kdybys setsakra moc chtěl. Stačí, aby ta třída měla (implicitně nebo explicitně) &&-konstruktor.

const Entity hermes{[] {
  Entity result;
  result.c = 1;
  result.b = 2;
  result.a = 3;
  return result;
}()};

Jenom bych se vsadil, že se ty typy dají uspořádat (a spořádaně konstruktory inicializovat) mnohem líp než takhle.

5.10.2021 03:06 Andrej | skóre: 51 | blog: Republic of Mordor
Rozbalit Rozbalit vše Re: [c++2a] Aggregate initialization

Mám ještě dojem, že kolem toho volání lambdy musí být extra závorky nebo tak něco. Kompilátor napoví. Ale to už jsou jenom technikálie (vzor: fekálie); princip zůstává.

Řešení 1× (Gréta)
5.10.2021 09:45 Michal Kubeček | skóre: 72 | Luštěnice
Rozbalit Rozbalit vše Re: [c++2a] Aggregate initialization
Odpovědět | | Sbalit | Link | Blokovat | Admin
atribúty musím pri inicializácii zadať v rovnakom poradí, ako som ich deklaroval v triede a nemôžem ich vynechať

g++ od verze 8 sice trvá na zachování pořadí, ale už lze inicializátory vynechávat (příslušný člen je pak null initialized jako v C).

Niečo sa mi marí, že v čistom (novom) C som raz videl aj iný spôsob zápisu (tuším každá propsa spolu s hodnotou bola obalená ešte v jednom páre zložených zátvoriek)

Nic tak komplikovaného, prostě jen místo anonymních inicializátorů použijete pojmenované. Funguje to už od C90:

#include <stdio.h>

struct entity {
        int     prop1;
        int     prop2;
        int     prop3;
};

int main()
{
        struct entity e = {
                .prop3  = 3,
                .prop1  = 1,
        };

        printf("prop1=%d, prop2=%d, prop3=%d\n", e.prop1, e.prop2, e.prop3);

        return 0;
}
mike@lion:/tmp/test> gcc-12 --std=c90 -Wall -Wextra -o x x.c
mike@lion:/tmp/test> ./x
prop1=1, prop2=0, prop3=3

Třicet let standardizovaná featura mi nepřijde až tak horká novinka. :-)

5.10.2021 09:59 Michal Kubeček | skóre: 72 | Luštěnice
Rozbalit Rozbalit vše Re: [c++2a] Aggregate initialization
Vnořené složené závorky jste možná mohl vidět, pokud se inicializovalo např. pole struktur nebo vnořené struktury.
6.10.2021 10:41 luky
Rozbalit Rozbalit vše Re: [c++2a] Aggregate initialization
Odpovědět | | Sbalit | Link | Blokovat | Admin
Prekladejte to C prekladacem a prilinkujte si to k C++ aplikaci.
6.10.2021 20:41 Jardík
Rozbalit Rozbalit vše Re: [c++2a] Aggregate initialization
Odpovědět | | Sbalit | Link | Blokovat | Admin
Tady např. vysvětlují důvod.

Podělaný semafory.

Založit nové vláknoNahoru

Tiskni Sdílej: Linkuj Jaggni to Vybrali.sme.sk Google Del.icio.us Facebook

ISSN 1214-1267, (c) 1999-2007 Stickfish s.r.o.