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?
Ups, ja, const int&. Wie kommst darauf, dass dem nicht so ist?
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
@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
inta;
2
int*constb=&a;// geht, const-Zeiger auf einen non-const-int
3
int&constc=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
inta;
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
inta;
2
int*constp=&a;
ist p mit einem top-level const ausgestattet: p selbst ist read-only und
nicht das Ziel.
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:> und bei "const int &", warum ist dieses kein top-level const?Return-Typ schrieb:> Bei "const T &", warum ist dieses const ein top-level const,>> und bei "const int &", warum ist dieses kein top-level const?
Was bedeutet "const int &"? Schreib es hin...
Oliver
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
intconst*const*const*constmyptr;
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.