Forum: Compiler & IDEs GCC variable templates + decltype bug?


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
von Vincent H. (vinci)


Bewertung
0 lesenswert
nicht 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. :)

: Bearbeitet durch User
Beitrag #5360248 wurde vom Autor gelöscht.
von Eric B. (beric)


Bewertung
0 lesenswert
nicht 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

: Bearbeitet durch User
Beitrag #5360265 wurde vom Autor gelöscht.
von Vincent H. (vinci)


Bewertung
1 lesenswert
nicht 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 ;)

von Wilhelm M. (wimalopaan)


Bewertung
1 lesenswert
nicht 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.

von Vincent H. (vinci)


Bewertung
0 lesenswert
nicht 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.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
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.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.