2017-02-05 1 views
0

Bitte beachten Sie folgenden Sudo-Code.Kann ich eine ausgewählte Referenz in C++ zurückgeben?

Object& getObjectDependingOnMonth(std::string& month, std::vector<Object>& vec) { 

    if (month == "January") { 
     auto& ref = vec.at(1); 
    } else { 
     auto& ref = vec.at(2); 
    } 

    ref.do_something(); // error because ref is local in block above. 

    return ref; // error because ref is local in block above. 
} 

Der obige Code zeigt, was ich tun möchte. Ich möchte eine Referenz des Elementes eines Vektors bekommen. Es hängt von einer Eingabe, einem Monat ab. Ich möchte seine Referenz außerhalb der Funktion, getObjectDependingOnMonth (...) verwenden. Ich konnte jedoch nicht darüber nachdenken, wie man eine gültige Referenz eines ausgewählten Elements im Vektor ohne doppelten Code in Blöcken zurückgibt. auto & ref = ... ist in einem if-Block definiert. Die Ref sind außerhalb ihres Blocks ungültig.

Kann ich eine ausgewählte Referenz von einer Funktion zurückgeben? Vielen Dank.

+0

Enthält diese kompiliert als 'ref' –

+0

@BeyelerStudios aus dem Geltungsbereich: Ich für meinen Fehler bedaure. Ich ändere std :: vector -> std :: vector & zeitlicher Vektor nicht zu verwenden. – mora

Antwort

5

einfach den Code ändern:

if (month == "January") { 
    auto& ref = vec.at(1); 
} else { 
    auto& ref = vec.at(2); 
} 

der folgenden, so dass Sie einen Referenz

auto& ref = vec.at(month == "January" ? 1 : 2); 
+0

danke für die mir eine Lösung zu sagen. Dank Ihrer Lösung erfahre ich, dass es wichtig ist, die Auswahl des Elements und die Zuordnung zur Referenz zu unterteilen. Vielen Dank. – mora

1

Ja !!

Object& getObjectDependingOnMonth(std::string& month, std::vector<Object>& vec) { 

    if (month == "January") { 
     vec.at(1).do_something(); 
     return vec.at(1); 
    } else { 
     vec.at(2).do_something(); 
     return vec.at(2); 
    } 

}

+0

Vielen Dank für die Antwort. Bitte lass mich dich mehr fragen. Mein Code hat viel Code nach vec.at(). Ihre Lösung benötigt in jedem Block viel doppelten Code. Kann ich es vermeiden? – mora

+0

Vielleicht sollte ich den gesamten Code in do_something() einfügen, um doppelten Code zu vermeiden. Vielen Dank. – mora

+0

Vielleicht lesen [DRY] (https://en.wikipedia.org/wiki/Don't_repeat_yourself) –

0

haben, wenn Sie wollen (Wieder-) Referenz zuweisen, benutze einfach den Zeiger anstelle der Referenz. Dereferenzieren Sie es bei der Rückkehr.

2

in C++ ist es sehr idiomatisch ist Iteratoren zu verwenden, um eine Position in einem Behälter angibt:

auto getObjectDependingOnMonth(const std::string& month, std::vector<Object>& vec) { 
    decltype(vec.begin()) pos; 

    if (month == "January") 
     pos = vec.size() > 1 ? vec.begin() + 1 : vec.end(); 
    else 
     pos = vec.size() > 2 ? vec.begin() + 2 : vec.end(); 

    if(pos != vec.end()) 
     pos->do_something(); 

    return pos; 
} 
+0

was ist, 'auto pos = std :: begin (vet);' und dann 'pos = std :: advance (pos, i);' keine Notwendigkeit für declltype oder der Bedingung Operator – dlavila

+0

@dlavila sicher, dass Sie das auch tun können Vergiss nicht, nicht am Ende vorbeizugehen ... – BeyelerStudios

+0

@BeyelerStudios: Danke, dass du mir eine andere Lösung erzählst. – mora

Verwandte Themen