GCC variable templates + decltype bug?

#5360222
Lesenswert?

Grüß euch

Ich hab ein komisches subtiles Problem mit variable templates und 
decltype. Aber vielleicht zuerst etwas Vorgeschichte... Ich nutze 
variable templates als Abkürzung um std::integral_constant Varianten für 
verschiedene Built-In Types zu erzeugen.

Es gibt also zum Beispiel
1
template<uint8_t I>
2
constexpr auto uint8_c{std::integral_constant<uint8_t, I>{}};

(Falls das jemandem bekannt vorkommt, ja, die Bezeichnung ist von Hana 
geklaut ;) )

Soweit so gut. Ich glaub wir sind uns alle einig dass folgendes gilt:
1
std::integral_constant<uint8_t, 42> == uint8_c<42>

Der Compiler (GCC 7.3.0-1) scheint da mit mir einer Meinung zu sein, 
is_same ergibt true und auch die Typenausgabe via boost-typeindex ist 
ident.


Und jetzt wirds irgendwie... komisch.
1
auto t = std::make_tuple(std::make_tuple(uint8_c<42>), 42);
2
auto get_works = get<std::integral_constant<uint8_t, 42>>(t);
3
auto get_doesnt_work = get<decltype(uint8_c<42>)>(t);

Während der erste Aufruf in meine eigene get-Funktion nämlich 
compiliert, tut es der 2. nicht. Der schießt sich mit einer 
static_assertion ab, dass der den Typen nicht findet.

Kennt jemanden einen Bug in Bezug auf decltype und variable templates? 
Da hats doch was oder?


/edit
Achja, die error-msg behauptet auch es is ein 
std:integral_constant<uint8_t, 42>...
1
required from constexpr decltype(auto) get(U&&) [with T = const std::integral_constant<unsigned char, 42>...

Ich versteh die Welt nimma. :)
Beitrag #5360248 wurde von einem Moderator gelöscht.
#5360249
Lesenswert?

Vincent H. schrieb:
> std::integral_constant<uint8_t, 42> == uint8_c<42>

> auto get_works = get<std::integral_constant<uint8_t, 42>>(t);
> auto get_doesnt_work = get<decltype(uint8_c<42>)>(t);

Das sieht für mich zwar aus wie schwarze Magie, wäre die 
Schlussfolgerung aus den ersten zwei Statements aber folgendes:
1
auto get_doesnt_work = get<uint8_c<42>>(t); // ohne decltype()

(Free free to downvote if this doesn't make sense! ;-D)

auch edit:
> Ich versteh die Welt nimma. :)

Den Anspruch habe ich schon längst aufgegeben :-D
Beitrag #5360265 wurde von einem Moderator gelöscht.
#5360294
Lesenswert?

Manchmal hat man echt einen Knoten im Kopf das gibts gar nicht...

Das Problem war der constexpr-qualifier. Der hat aus uint8_c immer eine 
constexpr gemacht, was sich natürlich am Typ wiederspiegelt. Der Typ 
integral_constant<uint8_t, 42> ist natürlich von sich aus nicht const.

Trotzdem Danke, ich geh mich schämen ;)
#5360849
Lesenswert?

Ok, das Problem ist gelöst: prima!

Geht mir aber auch manchmal so, dass ich const oder volatile 
Qualifizierungen in der Typinferenz vergesse. Deswegen habe ich es mir 
angewöhnt, womöglich die Qualifizierungen per std::remove_cv, etc. zu 
entfernen bei den entsprechenden Funktionen / Metafunktionen.

Im übrigen ist Vittoreo Romero und andere Kenner fast immer auf 
Stackoverflow unterwegs. Da hast Du bei "interessanten" Fragen recht 
schnell eine stimmige und freundliche(!) Antwort.
#5360960
Lesenswert?

Wilhelm M. schrieb:
> Ok, das Problem ist gelöst: prima!
>
> Geht mir aber auch manchmal so, dass ich const oder volatile
> Qualifizierungen in der Typinferenz vergesse. Deswegen habe ich es mir
> angewöhnt, womöglich die Qualifizierungen per std::remove_cv, etc. zu
> entfernen bei den entsprechenden Funktionen / Metafunktionen.
>
> Im übrigen ist Vittoreo Romero und andere Kenner fast immer auf
> Stackoverflow unterwegs. Da hast Du bei "interessanten" Fragen recht
> schnell eine stimmige und freundliche(!) Antwort.

Ja das mach ich meist eh auch und ich versteh auch nicht wieso die 
ganzen Standard Traits es nicht tun. Dinge wie ein std::is_array oder 
ähnliches machen auf "CV-Ref" ja eh keinen Sinn...

Aber bei einem "get" kann es schon sinnvoll sein zwischen const und 
nicht-const zu unterscheiden.
Beitrag #7410586 wurde von einem Moderator gelöscht.
Beitrag #7414683 wurde von einem Moderator gelöscht.
Beitrag #7414941 wurde von einem Moderator gelöscht.
Beitrag #7416082 wurde von einem Moderator gelöscht.
Beitrag #7416525 wurde von einem Moderator gelöscht.
Beitrag #7416773 wurde von einem Moderator gelöscht.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren