Auto-Keyword-Verhalten mit Referenzen

Lesezeit: 3 Minuten

Nehmen wir an, ich habe eine einfache C++-Klasse, die ein privates Mitglied und einen Getter enthält:

class MyClass
{
    private:
        double m_testValue = 1;

    public:
        double& getTestValue(){return m_testValue;}
} 

Nehmen wir nun an, ich möchte den Getter aufrufen, um meine Referenz zu erhalten und diesen Wert zu bearbeiten (und vor/nach Werten zu drucken).

auto testVal = myClassInstance.getTestValue();
std::cout << myClassInstance.getTestValue() << std::endl;
std::cout << testVal << std::endl;
testVal = 3;
std::cout << myClassInstance.getTestValue() << std::endl;
std::cout << testVal << std::endl;

Die Ausgabe ist

1
1
1
3

Das ist nicht genau das, was ich erwartet hatte, da m_testValue anscheinend nicht bearbeitet wurde. In der Tat, wenn ich auto durch double& ersetze:

double& testVal = myClassInstance.getTestValue();
std::cout << myClassInstance.getTestValue() << std::endl;
std::cout << testVal << std::endl;
testVal = 3;
std::cout << myClassInstance.getTestValue() << std::endl;
std::cout << testVal << std::endl;

Ich bekomme

1
1
3
3

Was ich will. Die Frage ist also: Ist dies das erwartete Verhalten des auto Stichwort oder Bug? Wenn dies erwartet wird, was ist der Grund für dieses Verhalten? ist es eine technische Einschränkung? Wenn es beabsichtigt ist und warum?

  • auto funktioniert genau wie die Vorlagentypableitung, mit einer Ausnahme ohne Bezug.

    – Chris

    23. Mai 2016 um 14:48 Uhr


  • Beachten Sie, dass Sie in C++14 das gewünschte Verhalten mit erhalten können decltype(auto).

    – TartanLama

    23. Mai 2016 um 14:50 Uhr

  • Dieser Kommentar bezieht sich nicht auf Ihr Problem. In Ihrem Code gibt es ein Problem mit dem Design: Eine Get-Methode muss const sein const double& getTestValue() const noexcept {return m_testValue;}. In diesem speziellen Fall vielleicht als Referenz zurückgeben, ist es irrilevant

    – Elvis Dukaj

    23. Mai 2016 um 15:05 Uhr

  • @elvis.dukaj: Ein Getter ist nicht notwendig consthaben wir zum Beispiel std::vector::at, std::vector::front, std::vector::operator[]… und wenn es das ist get Präfix, die das Ding machen const Für Sie gibt es kostenlose Funktion std::get<I>(std::tuple<Ts...>&)

    – Jarod42

    23. Mai 2016 um 16:16 Uhr

  • @ Jarod42 Der einzige Fall ist, wenn Sie ein Element aus einem Container abrufen. In allen anderen Fällen halte ich es für eine schlechte Idee: Wenn ich getSpeed() lese, glaube ich nicht, dass ich die Geschwindigkeit des Objekts ändere. Das führt nur zu Missverständnissen im Code.

    – Elvis Dukaj

    24. Mai 2016 um 7:44 Uhr

Wann auto abgeleitet wird, wird es nicht auf die Referenz abgeleitet. Es kommt immer auf den Wert an. Wenn Sie einen Verweis auf den zurückgegebenen Wert haben möchten, können Sie dies tun auto&, const auto& oder auto&&.

Und ja, es ist beabsichtigt. Jedes andere Verhalten wäre eigentlich ziemlich überraschend. Was noch schlimmer ist, es ist einfach, eine Referenz zu verwenden, wenn Sie möchten. Stellen Sie sich das jedoch vor auto würde eigentlich auf die Referenz zurückgeführt werden. Wie würden Sie (syntaktisch) daraus einen Wert machen?

  • Ich wusste nichts über die Auto&-Syntax! Dies macht den Zweck und die Verwendung von auto klarer. Vielen Dank

    – Basile Perrenoud

    23. Mai 2016 um 15:03 Uhr

1019220cookie-checkAuto-Keyword-Verhalten mit Referenzen

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy