Forum: PC-Programmierung return in Listeninitialisierer


von Markus (Gast)


Lesenswert?

Wozu dienen hier die zwei Zeilen mit dem return A() ?
1
#include <iostream>
2
3
class A {
4
public:
5
    void foo() const { std::cout << "A::foo() const\n"; }
6
    void foo() { std::cout << "A::foo()\n"; }
7
};
8
9
A bar() { return A(); }
10
const A cbar() { return A(); }
11
12
13
int main()
14
{
15
    bar().foo();  // calls foo
16
    cbar().foo(); // calls foo const
17
}

Warum nicht so?
1
#include <iostream>
2
3
class A {
4
public:
5
    void foo() const { std::cout << "A::foo() const\n"; }
6
    void foo() { std::cout << "A::foo()\n"; }
7
};
8
9
10
int main()
11
{
12
    A bar;
13
    const A cbar;
14
15
    bar.foo();  // calls foo
16
    cbar.foo(); // calls foo const
17
}

(eigentlich dient der Code zur Veranschaulichung CV-qualifizierter 
r-values)

von Oliver S. (oliverso)


Lesenswert?

Markus schrieb:
> Warum nicht so?

Der erste Fall ruft foo über Funktionen (const/nicht const) auf, deine 
Lösung dagegen über Variablen (const/nicht const).

Auch wenn es ähnliche aussieht, ist das nicht das selbe. Das const 
steckt da an verschiedenen Stellen.

Ob das für den Demonstrations- und Lerneffekt wichtig ist, keine Ahnung. 
Da fehlt der Kontext des Beispiels.

Oliver

: Bearbeitet durch User
von MaWin (Gast)


Lesenswert?

Hoffentlich steht bei dem Beispiel auch fett dabei:

Mach das nicht!

Denn const und nicht-const zu überladen, ist sehr verwirrend. Da blickt 
am Ende niemand mehr durch.

von Oliver S. (oliverso)


Lesenswert?

MaWin schrieb:
> Denn const und nicht-const zu überladen, ist sehr verwirrend. Da blickt
> am Ende niemand mehr durch.

Das ist leider eine der Ecken in C++, erforderlich sind, aber kaum schön 
gelöst werden können.

Oliver

von Markus (Gast)


Lesenswert?

Oliver S. schrieb:
> Der erste Fall ruft foo über Funktionen (const/nicht const) auf, deine
> Lösung dagegen über Variablen (const/nicht const).

Ähhhh, jetzt wo du es sagst....
Ich hatte die Klammern übersehen und es so gelesen, daß ein Objekt bar 
der Klasse A angelegt wird.

von Wilhelm M. (wimalopaan)


Lesenswert?

Was hat das Thema mit Listen zu tun?

Meinst Du wirklich die Unterscheidung ro/rw bei return-Werten?

Oder meinst Du die ref-Qualifikation von Elementfunktion? Also, ob eine 
Elementfunktion auf ein rvalue oder lvalue anwendbar ist (ich meine 
nicht die Parameterliste).

Ersteres ist bei primitiven DT sinnlos und bei UDT ggf. schlecht, weil 
es ein move ggf. verhindert.

: Bearbeitet durch User
von Markus (Gast)


Lesenswert?

Wilhelm M. schrieb:
> Was hat das Thema mit Listen zu tun?

Gar nichts, ich wußte nicht, welcher Titel am besten paßt: Anstatt
1
A bar() { return A(); }
 las ich
1
A bar { return A(); }
 und wunderte mich über das { return A(); }. Wie nennst du hier die 
geschweiften Klammern?
Mit dem eigentlichen Thema des Beispiels hat meine Frage gar nichts zu 
tun, denn:

> Meinst Du wirklich die Unterscheidung ro/rw bei return-Werten?

Darauf läuft es im Buch hinaus, Überladen von const und nicht-const.
Zuvor muß ich aber lvalues und rvalues verstehen...


> Oder meinst Du die ref-Qualifikation von Elementfunktion? Also, ob eine
> Elementfunktion auf ein rvalue oder lvalue anwendbar ist (ich meine
> nicht die Parameterliste).
> Ersteres ist bei primitiven DT sinnlos und bei UDT ggf. schlecht, weil
> es ein move ggf. verhindert.

Was immer damit gemeint sein mag, ich bin davon noch weit entfernt ;-)

von Wilhelm M. (wimalopaan)


Lesenswert?

Markus schrieb:
> Wilhelm M. schrieb:
>> Was hat das Thema mit Listen zu tun?
>
> Gar nichts, ich wußte nicht, welcher Titel am besten paßt:

Dann wundere Dich nicht über wenige Beiträge zum eigentlichen Thema ;-)

> Anstatt
1
A 
2
> bar() { return A(); }
 las ich
1
A bar { return A(); }
 und
> wunderte mich über das { return A(); }. Wie nennst du hier die
> geschweiften Klammern?

Der Funktionskörper ist ein Block: die geschweiften Klammen sind die 
Block-Begrenzer.

>> Meinst Du wirklich die Unterscheidung ro/rw bei return-Werten?
>
> Darauf läuft es im Buch hinaus, Überladen von const und nicht-const.

Bzgl. des Rückgabetyps kannst Du in C++ nicht überladen: der Typ der 
Funktion ist nicht Bestandteil der Signatur, deswegen ist solches 
Vorgehen kein korrektes Überladen.

Von Überladen spricht man, wenn die Signatur sich unterscheidet, aber 
der Name (Bestandteil der Signatur) gleich bleibt:
1
void f();
2
void f(int);

oder
1
struct A {
2
   voif f();
3
   voif f() const;
4
};

> Zuvor muß ich aber lvalues und rvalues verstehen...

Betrachte rvalues als temporäre-anonyme Objekte.

>> Oder meinst Du die ref-Qualifikation von Elementfunktion? Also, ob eine
>> Elementfunktion auf ein rvalue oder lvalue anwendbar ist (ich meine
>> nicht die Parameterliste).
>> Ersteres ist bei primitiven DT sinnlos und bei UDT ggf. schlecht, weil
>> es ein move ggf. verhindert.
>
> Was immer damit gemeint sein mag, ich bin davon noch weit entfernt ;-)

Ok, dann vergiss es fürs erste. Es geht um:
1
struct A {
2
    void f() &; 
3
    void f() &&;
4
};
5
6
A foo();
Im ersten Fall muss das Objekt, für dass f() aufgerufen wird (bspw: 
a.f()) ein lvalue sein, im zweiten Fall ein rvalue (bspw: foo().f() ).

von mikro77 (Gast)


Lesenswert?

Ich weiß nicht was sich der Autor dabei gedacht hat:

Markus schrieb:
1
const A cbar() { return A(); }

Const für einen Rückgabewert auf ein Value (also keine Referenz/Pointer) 
macht keinen Sinn. Zumindest ist mir kein Fall bekannt und ich habe noch 
von keinem Fall gelesen, wo es sinnvoll ist. Außer natürlich wie hier um 
clever zu demonstrieren wann nicht/const Funktionen aufgerufen werden. 
/Ironie

Z.B. 
https://www.sandordargo.com/blog/2020/11/18/when-use-const-3-return-types

Aber selbst Scott Meyers war damals drauf reingefallen (in seinem Buch) 
und hat es erst später korrigiert. ;-)

von Markus (Gast)


Lesenswert?


Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.