2017-04-17 5 views
1

ich versuchte, aus codefights.com und bemerkte jemandes Antwort auf eine Frage, die alle längsten Strings in einem Vektor tun dies beteiligt geben:Variablendeklaration in Funktionsrückgabe Typspezifizierer C++ Typ

std::vector<std::string> r, allLongestStrings(std::vector<std::string> a) { 
    int b=0; 
    for (s:a) if (s.size()>b) b=s.size(); 
    for (s:a) if (s.size()==b) r.push_back(s); 
    return r; 
} 

Er erklärt eine Variable in der Rückgabetyp-Spezifizierer für die Funktion, kann mir jemand sagen, warum dies erlaubt ist? Ich kompiliere nicht auf meinem Rechner und ich konnte keine gcc-Erweiterung finden, die das tut, danke im Voraus :).

+3

Sind Sie sicher, dass die Lösung funktioniert? Wie geschrieben, scheint dies nicht gültig C++ zu sein. – merlin2011

+1

Nicht gültig C++ in keiner Weise. Diese Form des Ranged-For wurde von bestimmten Versionen von GCC erlaubt, wurde aber später entfernt, da der Standard dies verbietet. Wie zum Deklarieren einer Variable im Rückgabetyp ... Was? – DeiDei

+0

Ich weiß !, die for-Schleifen verwirrten mich auch, aber es funktioniert auf der Codefights-Website und besteht alle Tests: S –

Antwort

1

Mit Blick auf die reference (Decl-specifier-Seq), sehe ich nicht, wie es möglich wäre, die Rückgabevariable vor dem Funktionsnamen zu erklären.

Mit C++ 14, können Sie das auto Schlüsselwort verwenden das Duplikat entfernen des Rückgabetyp zu erwähnen:

auto allLongestStrings(const std::vector<std::string>& a) { 
    std::vector<std::string> r; 
    std::size_t b = 0; 
    for(const auto& s : a) if(s.size() > b) b = s.size(); 
    for(const auto& s : a) if(s.size() == b) r.push_back(s); 
    return r; 
} 

Ich reparierte einige andere Dinge des Codes:

  • zu verbessern Effizienz, deklarieren Sie den Parameter a als const Referenz, so wird es nicht kopiert
  • deklarieren Sie b als std::size_t mit Rückgabetyp von std::vector::size() übereinstimmen
  • in Bereich-for-Schleife, ein Typ-Spezifizierer ist notwendig (auch wenn es ist); hinzugefügt konstante Referenz für Effizienz

Live demo.

+0

Ich denke, das ist ein Komma-Operator dort und ist ein Exploit von Test-Unit-Code <. <; – Swift

0

Die gemischte Variable/Funktion Erklärung scheint in Ordnung zu sein, obwohl gcc, dass Funktionsdefinition klagt nicht da sein sollte, aber ich denke, es ist im globalen Bereich ist ok. Aber es ist eine 100% gültige Syntax auch im nicht-globalen Bereich, wenn keine Funktionsdefinition angegeben ist. Diese Deklaration ist nur eine regelmäßige Deklaration mehrerer Elemente desselben führenden Typs. Zum Beispiel können wir mehrere Elemente verschiedener Arten erklären, aber mit dem gleichen wie dem führenden:

// single line declaration 
int i = 0, * p_i = nullptr, ai[2] = {42,42}, geti(void), * * getppi(void); 
// the same as 
int i = 0; 
int * p_i = nullptr; 
int ai[2] = {42, 42}; 
int geti(void); 
int ** getppi(void); 

So r sind nur eine ganz normalen Variablen vom Typ std::vector<std::string>, durch die Funktion allLongestStrings gefolgt, die den gleichen std :: zurück Vektortyp.

Diese kompakte Deklarationsform existiert aus historischen Gründen. Im Grunde half es, einige Bytes zum Speichern und Kompilieren der Quelldatei zu speichern.

Diese Form von for Schleife ist wahrscheinlich eine der früheren experimentellen Erweiterungen vor der aktuellen Form wurde standardisiert.

+0

Ihr Beispiel zeigt das Mischen von Variablendeklarationen mit Funktionsdeklarationen.Der OP-Code vermischt eine Variablendeklaration mit einer Funktionsdefinition, was nicht dasselbe ist und nicht erlaubt ist. – interjay

+0

nein, es ist nicht ok im globalen Bereich .. ich versuche herauszufinden, welche Wrapper sie verwenden, aber scheitern, mindestens alle modernen Compiler werden durch Fehler bei jedem Versuch, variable Deklaration und Funktionsdefinition über Komma zu kombinieren ... entweder sie haben sehr veralteter oder exotischer Compiler und und ihr Wrapper ist eine Art Vorlage, in der Antwort eingefügt wird oder etwas wirklich Seltsames dort passiert – Swift

+0

[IntelCC scheint erlauben] (https://godbolt.org/g/7JERJT) Putting Funktionsdefinition in Globaler Umfang nach Variable wie im Beispiel von OP. – VTT