2016-05-21 16 views
3

Ich mag die Zeichenfolge Splitting-Funktion für die höchsten bewertete Antwort auf diese Frage verwenden:Warum "std :: vector <std::string> &" statt "void"?

Split a string in C++?

die Antwort für Bequemlichkeit Kopieren:

#include <string> 
#include <sstream> 
#include <vector> 

std::vector<std::string> &split(const std::string &s, char delim, std::vector<std::string> &elems) { 
    std::stringstream ss(s); 
    std::string item; 
    while (std::getline(ss, item, delim)) { 
     elems.push_back(item); 
    } 
    return elems; 
} 


std::vector<std::string> split(const std::string &s, char delim) { 
    std::vector<std::string> elems; 
    split(s, delim, elems); 
    return elems; 
} 

ich hier eine Frage habe. Warum ist die Deklaration std::vector<std::string> &split(...) anstatt void split(...)? Als Argument erhalten wir std::vector<std::string> &elems und das ist, was wir am Ende haben wollen. Warum etwas zurückgeben, wenn wir eine Referenz erhalten?

ich habe:

int &multA (int &n) 
{ 
    n = 5*n; 
    return n; 
} 

void multB (int &n) 
{ 
    n = 5*n; 
} 

und:

int n1, n2; 
n1 = 1; 
n2 = 1; 
cout << "n1: " << n1 << endl; 
cout << "n2: " << n2 << endl; 
n1 = multA(n1); 
multB(n2); 
cout << "n1: " << n1 << endl; 
cout << "n2: " << n2 << endl; 

Und als Ergebnis habe ich:

n1: 1 
n2: 1 
n1: 5 
n2: 5 

Was dann ist der Unterschied?

+2

Es ist nur eine Bequemlichkeit, so dass Sie den Rückgabewert als Lvalue verwenden können, falls gewünscht. – Aenimated1

+0

Es sollte etwas mit Speicherverwaltung zu tun haben –

Antwort

5

einen Referenzzurück ermöglicht ein Aufruf an split() auf eine andere Funktion als ein Argument verwendet werden soll.Zum Beispiel nehmen wir eine andere Funktion haben, die einen Vektor von Strings durch Verweis

void func(std::vector<std::string> &elements); 

Wenn split() liefert eine Referenz nimmt, ist es möglich, die Referenz zu übergeben direkt an func() zurückgibt.

func(split(s, delim, elems)); 

während, wenn split() keinen Verweis zurückkehrte, wäre es notwendig,

split(s,delim, elems); 
    func(elems); 

Das zweite Verwendungs ​​Ansatz noch zu tun, funktioniert, wenn split() einen Verweis zurückgibt.

Der Unterschied zwischen diesen beiden ist reiner Programmierer Bequemlichkeit, aber viele Programmierer bevorzugen, den ersten Aufrufstil zu verwenden. Das Zurückgeben einer Referenz ist keine besonders teure Operation, so dass der Programmierer nicht viel verliert, wenn er die Wahl hat, wie er verwendet werden soll.

1

Es gibt keinen Unterschied in den von Ihnen geposteten Beispielen.

Aber es kann sein, wenn Sie es einer anderen Variablen zuweisen und/oder es an eine Funktion übergeben möchten.

int a = multA(n1); //In one line :) 
foo(multA(na1)); //Same thing, one line only 

multB(n1); 
int a = n1; //Two lines 

multB(n1); 
foo(n1); //Two lines 

Hier multA ist deutlich besser, weil man es in einer Zeile schreiben, statt 2 mit multB. Also im Grunde der einzige Unterschied.

3

Es ist syntaktischer Zucker, der die Funktionen flexibler macht.

Am Beispiel: Sie

std::cout << "there are " << split(str, delim, vect).size() << " elemements\n"; 

Mit dem void Hypothese Fall schreiben können, müssen Sie zwei Aussagen.

+1

Es wäre korrekter, das Wort "Anweisungen" statt "Anweisungen" zu verwenden. – Peter

+0

@ Peter - danke; Ich bin kein englischer Muttersprachler, so oft scheitere ich mit den richtigen Begriffen (und vielleicht irre ich mich auch in meiner Sprache); Ich korrigiere meine Antwort. – max66

+1

Kein Problem, aber das Englisch in Ihrer Antwort war (und ist) in Ordnung. Das Wort "statement" hat in C++ eine spezifische Bedeutung. Das Wort "Anweisung" (in diesem Zusammenhang) hat eine besondere Bedeutung in der Informatik, die sich von einer Aussage in C++ unterscheidet. Dieses Codebeispiel, das Sie angegeben haben, ist eine einzelne C++ - Anweisung. – Peter

0

In Bezug auf das Ergebnis gibt es keinen Unterschied zwischen diesen beiden Methoden.

Option 1 macht jedoch deutlich, dass die Funktion multA ein Berechnungsergebnis hat und dass das Ergebnis zurückgegeben wird.

n1 = multA(n1); 

Auf der anderen Seite ist die zweite Option nicht so selbsterklärend wie die erste. Sie können nicht einfach sagen, was multB tut, indem Sie den folgenden Code lesen. Es könnte sein, dass multB nur ein Ergebnis mit std::cout protokolliert. Aber Sie können nicht sagen, ohne die Funktionsdefinition zu lesen.

multB(n2); 
Verwandte Themen