GCC variable templates + decltype bug?

OP #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.
OP #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.
OP #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

Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt. Bitte hier nur auf die ursprüngliche Frage antworten, für neue Fragen einen neuen Beitrag erstellen.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.