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

Gast #7253276
Lesenswert?

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.
#7253399
Lesenswert?

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
#7253477
Lesenswert?

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?
#7253685
Lesenswert?

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.
#7254077
Lesenswert?

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 #7254156
Lesenswert?

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?
#7254693
Lesenswert?

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

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