C++: Unerwarteter Return-Typ von Template-Funktion

Gast #7253276
Guten Abend.
Kann mir jemand sagen, welchen return-Typ man erhält, wenn man eine 
Funktion/Methode
1
const T& fkt()  hat, mit  T = int&  ?
2

3
const T& fkt()  hat, mit  T = int   ?
Erwartet hätte ich in beiden Fällen ein "const int&". Das scheint aber 
falsch zu sein.
Kennt jemand ein Stichwort zu dem Thema zum Nachlesen, oder kann mir 
jemand so erklären, was da los ist?

Danke schon mal,
MfG.
Return-Typ schrieb:
> Aber warum kein 'const'?? Warum wird T nicht mit 'const' dekoriert?

Aus https://en.cppreference.com/w/cpp/language/reference (Link von 
Löppt):

"Reference types cannot be cv-qualified at the top level; there is no 
syntax for that in declaration, and if a qualification is added to a 
typedef-name or decltype specifier, (since C++11) or type template 
parameter, it is ignored."

  Michael
Gast
@Löppt: Der Compiler meckert.

Uhhh. Danke. Das hatte ich überlesen, mangels Verständnis.
Was bedeutet "top level"?
Und wieso ist das so?
Das wirkt irgendwie unintuitiv.
Return-Typ schrieb:
> Uhhh. Danke. Das hatte ich überlesen, mangels Verständnis.
> Was bedeutet "top level"?

Eine Referenz kann nicht const sein, sondern nur auf etwas als const 
verweisen, anders als bei Zeigern.
1
int a;
2
int* const b = &a; // geht, const-Zeiger auf einen non-const-int
3
int& const c = a;  // ergibt keinen Sinn und ist syntaktisch nicht erlaubt

> Und wieso ist das so?

Weil Referenzen sowieso nicht geändert werden können. Jeglicher Zugriff 
geht nicht auf die Referenz selber, da sie gar kein Objekt ist, sondern 
auf das, worauf sie verweist. Was sollte es also bringen, sie const zu 
machen?
Wenn Du fkt<int&>() instantiierst, ist demzufolge T dann int&. Im Typ 
der Funktion steht dann im Prinzip: const (int&)&. Wie schon gesagt sind 
Referenz-Typen nicht zusätzlich top-level mit const qualifizierbar, weil 
das sinnlos ist. Daher wird das const ignoriert. Das liefert dann: 
(int&)&, was wieder wegen reference-collapsing zu int& wird.
Return-Typ schrieb:
> Ich tue mich etwas schwer mit dem Begriff "Top Level".
> Top Level von was?

In
1
int a;
2
int& r = a;

ist r unveränderlich. Referenzen können nicht zur Laufzeit auf andere 
Objekte verweisen wie Zeiger. Deswegen ist es unsinnig und auch 
syntaktisch gar nicht möglich, eine Referenz an sich read-only zu 
machen, weil sie es bereits sind.

> Und warum ist das const in "const T &" kein top-level?

Weil es gar keine Syntax für ein top-level const von Referenzen gibt.

Hier
1
int a;
2
int* const p = &a;

ist p mit einem top-level const ausgestattet: p selbst ist read-only und 
nicht das Ziel.
Gast
Wie gesagt, dass Referenzen nicht umgebunden werden können, ist klar. 
Was aber geht, ist auf ein non-const Objekt mittels "Referenz auf const" 
zuzugreifen.

Bei "const T &", warum ist dieses const ein top-level const,

und bei "const int &", warum ist dieses kein top-level const?

Bei "const T &" hätte ich auch die Anweisung "Zugriff mittels Referenz 
auf const" vermutet. Wenn es das nicht ist, wie würde man das dann in 
Worte fassen können?
Return-Typ schrieb:
> Ich tue mich etwas schwer mit dem Begriff "Top Level".
> Top Level von was?

Von der Referenzierung.

> Und warum ist das const in "const T &" kein top-level?

Weil es sich nicht auf die Referenz, sondern auf das referenzierte 
Objekt bezieht.

Return-Typ schrieb:
> Wie gesagt, dass Referenzen nicht umgebunden werden können, ist klar.
> Was aber geht, ist auf ein non-const Objekt mittels "Referenz auf const"
> zuzugreifen.
>
> Bei "const T &", warum ist dieses const ein top-level const,

Ist es nicht. Bei T & const wäre es top-level, wenn es denn sowas gäbe.

> und bei "const int &", warum ist dieses kein top-level const?

Genau wie oben: Weil es sich nicht auf die Referenz selbst bezieht, 
sondern auf das referenzierte Objekt. Vielleicht wird es bei Zeigern 
etwas klarer, wo es mehr Ebenen der "Verzeigerung" geben kann:
1
int const * const * const * const myptr;

Hier gibt es quasi vier Ebenen, die alle const sind, daher viermal 
const. Die oberste Ebene, also top-level const, ist das letzte in dieser 
Reihe. Bei Referenzen geht das alles nicht. Weder gibt es mehr als zwei 
Ebenen, noch gibt es auf oberster Ebene die Möglichkeit, sie const zu 
machen.

> Bei "const T &" hätte ich auch die Anweisung "Zugriff mittels Referenz
> auf const" vermutet.

Da hast du richtig vermutet.

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 3 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

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.