2017-05-19 3 views
-1

Was ist der richtige Weg, um NULL-Zeichenfolgen an eine Funktion zu übergeben, ohne eine Variable zu erstellen? Ich sehe Kompilierungsfehler mit folgendem Code und ich möchte die Definition nicht ändern. Möglicherweise müssen Sie auch die Zeichenfolge ändern, um sie nicht als konstanten Typ zu markieren.Übergeben der Nullzeichenfolge, um als Argument zu fungieren

#include <iostream> 
#include <string> 

using namespace std; 
void 
myfunc(int i, string &my) { 
    if (my.empty()) { 
     cout << "Empty" << endl; 
    } else { 
     cout << "String is " << my <<endl; 
    } 
} 
int main() 
{ 
    std::string str1 ("Test string"); 
    myfunc(1, str1); 
    std::string str2 (""); 
    myfunc(2, ""); 
    return 0; 
}` 

my1.cpp: 18: Fehler: ungültige Initialisierung nicht const Referenz vom Typ 'std :: string &' von einem temporären des Typs 'const char *' my1.cpp: 6: Fehler: in Gabe des Arguments 2 von 'Leeren myfunc (int, std :: string &) '

nach compiliert, aber ich mag nicht lokalen Variable

#include <iostream> 
#include <string> 

using namespace std; 
void 
myfunc(int i, string &my) { 
    if (my.empty()) { 
     cout << "Empty" << endl; 
    } else { 
     cout << "String is " << my <<endl; 
    } 
} 
int main() 
{ 
    std::string str1 ("Test string"); 
    myfunc(1, str1); 
    std::string str2 (""); 
    myfunc(2, str2); 
    return 0; 
} 
+1

Sie übergeben als Referenz bedeutet, die Adresse der Variablen nicht den Wert übergeben. wenn Sie nach Wert übergeben möchten. – Raindrop7

+0

Referenzen werden normalerweise als verdeckter Zeiger implementiert, aber dies wird vom Standard nicht benötigt. Was ** erforderlich ist ** ist, dass die Referenz tatsächlich auf ein korrektes Objekt verweist. –

+0

@ Raindrop7, Haben wir einen Weg, auf dem wir einen Verweis auf String übergeben können, ohne ein Objekt zu erstellen? – Tectrendz

Antwort

3

Die Lösung hier ist eine Überladung, die nicht den String-Parameter hat.

void myfunc(int i, string &my) { 
     cout << "String is " << my <<endl; 
} 

void myfunc(int i) { 
    cout << "Empty" << endl; 
} 

int main() 
{ 
    std::string str1 ("Test string"); 
    myfunc(1, str1); 
    myfunc(2); 
} 

Dies ist die einfache und klare Lösung, die genau auf Ihre Absicht und Funktionalität vermittelt.

Sie sollten nicht versuchen, es auf Ihre Weise zu tun, denn wenn Sie das Argument ändern wollen, dann sollte der Parameter "non-const reference" sein und kann daher nicht an Provisorien binden. Daher können Sie kein Zeichenfolgenliteral übergeben.


Wenn Sie es explizit machen möchten, dass Sie nicht über eine Zeichenfolge übergeben, können Sie einen Tag ala nullptr schaffen, obwohl ich die zusätzliche Komplikation nicht empfehlen, wenn die obige Variante von jedem klar und verständlich ist erster Blick.

struct no_string_tag_t {}; 
constexpr no_string_tag_t no_string_tag; 

void myfunc(int i, string &my) { 
     cout << "String is " << my <<endl; 
} 

void myfunc(int i, no_string_tag_t) { 
    cout << "Empty" << endl; 
} 

int main() 
{ 
    std::string str1 ("Test string"); 
    myfunc(1, str1); 
    myfunc(2, no_string_tag); 
} 

Wenn Sie wirklich eine einzelne Funktion wollen, dann ist die semantisch korrekte Version würde eine optionale Referenz.

auto foo(int i, std::optional<std::reference_wrapper<std::string>> my) 
{ 
    if (my) 
     cout << "String is " << my <<endl; 
    else 
     cout << "no string" << endl; 

} 
int main() 
{ 
    std::string str1 ("Test string"); 
    myfunc(1, str1); 
    myfunc(2, std::nullopt); 
} 

Wenn Sie die Funktion Signatur behalten möchten und noch in der Lage sein, es vorübergehend zu passieren, dann sind Sie kein Glück.C++ hat eine Sicherheitsfunktion, da es nicht erlaubt, dass eine nicht-konstante Instanz an ein temporäres bindet. Der Grund für diese Einschränkung ist, dass der Versuch, ein temporäres über eine Referenz zu modifizieren, höchstwahrscheinlich ein Fehler ist und nicht die Absicht des Programmierers, da das temporäre sowieso ausstirbt.

0

Sie können keine temporäre zu einem nicht passieren erstellen -const Referenzpar ein Meter. Das Objekt, das temporär ist, wird zerstört, sobald die Funktion zurückkehrt. Alle Änderungen, die die Funktion an das Objekt vorgenommen hat, würden verloren gehen.

Wenn Sie die Möglichkeit haben möchten, die Zeichenkette zu ändern, können Sie die Zeichenkette mit const referenzieren und eine modifizierte Zeichenkette zurückgeben.

string myfunc(int i, string const &s); 
: 
str1 = myfunc(1, str1); 
auto result2 = myfunc(2, ""); 

Ihre andere Option besteht darin, einen Zeiger auf eine Zeichenfolge zu verwenden, die null sein kann.

void myfunc(int i, string *s) { 
    if (!s) { 
     cout << "Empty" << endl; 
    } else { 
     cout << "String is " << *s <<endl; 
    } 
} 

myfunc(1, &str1); 
myfunc(2, nullptr); 
Verwandte Themen