Wieso kann man in C++ keine Strings mit Ints verknüpfen?


  • Mod

    Beide Funktionsaufrufe sind ill-formed, falls der Compiler das anders sieht, erlaubt das nur Rückschlüsse bezüglich dessen Standardkonformität. Was geht bzw. geht-nicht bedeuten soll, weis ich nicht. "Temporär" kann man nicht steigern :p



  • geht bedeutet, dass es der compiler übersetzt.
    geht nicht bedeutet, dass der compiler an dieser zeile stehen bleibt und den fehler bemängelt.

    dann haben wir also offiziell nicht-standardkonformes verhalten in visual c++ 2005 ausgemacht?



  • Bashar schrieb:

    groovemaster schrieb:

    Bashar schrieb:

    groovemaster schrieb:

    '~' ist immerhin auch der Operator für bitweise Negierung.

    Nein, das ist der unäre Operator.

    Und nachts ist es kälter als draussen. 🙂 Ob unär oder nicht ist bezugslos zu meiner Aussage. '~' ist und bleibt ein Operator.

    Aber du hast schon verstanden, was ich ausdrücken will?

    Klar. Nur ging es mir ja um einen separaten Operator, der bisher noch nicht verwendet wird. Ob unär, binär oder ternär spielt dabei keine Rolle. Daher war dein Kommentar etwas unpassend. Oder glaubst du, mir ist nicht bewusst, dass '~' für binäre Verknüpfungen noch nicht verwendet wird?



  • groovemaster schrieb:

    Bashar schrieb:

    Aber du hast schon verstanden, was ich ausdrücken will?

    Klar. Nur ging es mir ja um einen separaten Operator, der bisher noch nicht verwendet wird.

    Das stört bei anderen Operatoren (wie * und &) doch auch keinen, also muss die Frage erlaubt sein, warum du diese Analogie ignorierst.



  • falsch schrieb:

    Jetzt bin ich verwirrt:

    void foo2( int& a )
    {
    	std::cout << a << std::endl;
    }
    
    void foo3( std::string& s)
    {
    	std::cout << s << std::endl;
    }
    
    int main()
    {
        foo2(10); // geht nicht
        foo3(std::string("temp")); // geht
        return 0;
    }
    

    Ich sehe da nicht so den massiven Unterschied...

    FAQ: http://www.c-plusplus.net/forum/viewtopic-var-t-is-39474.html



  • Sorry, habe alle Antworten vorher nicht gesehen!!!

    weil beim std::string der += operator für den Typ int nicht implementiert ist.
    Das kannst du aber selber machen oder die eine eigene String Klasse schreiben,
    die das macht. In anderen Sprachen haben sich eben die Entwickler die Mühe gemacht,für solche Probleme eine Funktion oder eben einen operator zu schreiben.
    Man sollte deshalb aber nicht über C++ meckern.
    Sorry, habe alle Antworten vorher nicht gesehen!!!



  • falsch schrieb:

    geht bedeutet, dass es der compiler übersetzt.
    geht nicht bedeutet, dass der compiler an dieser zeile stehen bleibt und den fehler bemängelt.

    dann haben wir also offiziell nicht-standardkonformes verhalten in visual c++ 2005 ausgemacht?

    Schmeißt er wenigstens ne Warnung raus? Kann man ihn vielleicht in einen megakonformen Modus schalten in dem er sowas ablehnt?


  • Mod

    .filmor schrieb:

    Kann man ihn vielleicht in einen megakonformen Modus schalten in dem er sowas ablehnt?

    Selbstverständlich gibt es diesen (und ist auch nicht schwer zu finden)- was bedeutet, dass falsch seine Hausaufgaben nicht gemacht hat. Das wiederum war der Grund, warum ich gar nicht erst darauf hingewiesen habe.



  • hgfdsa schrieb:

    camper schrieb:

    hgfdsa schrieb:

    Warum geht das bei stringstream aber nicht bei string?

    DrakoXP täuscht sich hier. Eine solche Überladung führt nicht zu Mehrdeutigkeiten, wenn das Argument 0 ist, da habe ich auch nicht aufgepasst.

    std::string& operator+(std::string& str, int i)
    {
        std::stringstream ss;
        ss << i;
        str += ss.str();
        return str;
    }
    
    int main(int argc, char** argv) {
    
    	int i = 0;
    	std::stringstream stream;
    	stream << "NULL = ";
    	stream << i; //geht
    	stream << 0; //geht
    
    	std::cout<<stream.str();
    
    	std::string strNull = "Null = ";
    	strNull += i; //geht
    	strNull += 0; //geht nicht
    
    	return 0;
    }
    

    Mit Visual Studio 2008 kompiliert das letzte aber nicht

    error C2593: 'Operator +=' ist mehrdeutig

    Warum?

    Warum ist es denn nun genau bei "+=0" Mehrdeutig?
    Und vorallem warum geht dann das?

    strNull = strNull + 0;
    

    Hat das irgend nen sinnvollen Grund, oder ist das nur ein komischer Nebeneffekt?


  • Mod

    hgfdsa schrieb:

    Warum ist es denn nun genau bei "+=0" Mehrdeutig?

    Weil die beiden Kandidaten

    std::string& std::string::operator+=(const char* s);
    std::string& std::operator+=(char c);
    

    eine gleich gute Wahl darstellen (der 3. Kandidat

    std::string& std::string::operator+=(const std::string& str);
    

    benötigt einen Konvertierungskonstruktor und ist deshalb schlechter). Keiner dieser Kandidaten ist eine Templatefunktion.

    Und vorallem warum geht dann das?

    strNull = strNull + 0;
    

    Mit deiner einem eigenen Operator ist das doch kein Problem? Keiner der Standardüberladungen von operator+ für std::string kommt in Frage, denn dabei handelt es sich ausnahmslos um Templates, keines davon verfügt über eine Spezialisierung die zu den deduzierten Parametertypen passt.



  • camper schrieb:

    hgfdsa schrieb:

    Warum ist es denn nun genau bei "+=0" Mehrdeutig?

    Weil die beiden Kandidaten

    std::string& std::string::operator+=(const char* s);
    std::string& std::operator+=(char c);
    

    eine gleich gute Wahl darstellen

    Und Warum ist es bei jeder anderen Zahl dann eindeutig? Was ist der Grund dafür, dass man annimmt, dass 0 mehr Pointer ist als alle andere Zahlen? Warum sagt man nicht 0 ist wie jede andere Zahl auch erst mal int, und nur wenn man ne Zahl eindeutig nem Pointer zuweist, dann ist es eine Adresse?



  • hgfdsa schrieb:

    Und Warum ist es bei jeder anderen Zahl dann eindeutig? Was ist der Grund dafür, dass man annimmt, dass 0 mehr Pointer ist als alle andere Zahlen? Warum sagt man nicht 0 ist wie jede andere Zahl auch erst mal int, und nur wenn man ne Zahl eindeutig nem Pointer zuweist, dann ist es eine Adresse?

    Zeiger können auch die Adresse 0 haben, was darauf hinweist, dass sie auf kein Objekt zeigen. Man spricht dann von Nullzeigern (NULL-Pointer).
    Beim Aufruf überladener Funktionen (Operatoren) sollten die Parameter eindeutig sein, damit bestimmt werden kann, welche Funktion (bzw. welcher Operator) aufgerufen wird.



  • warum benutzt ihr nicht stringstreams anstatt strings. Da ist das anhängen mit egal was für Daten überhaupt kein Problem. Warum überläd man denn sonst den operator << bei meinen Klassen?



  • Krux schrieb:

    warum benutzt ihr nicht stringstreams anstatt strings. Da ist das anhängen mit egal was für Daten überhaupt kein Problem. Warum überläd man denn sonst den operator << bei meinen Klassen?

    Darauf hab ich bis jetzt bereits drei Mal hingewiesen, aber es gibt hier einige Leute, die eine fundamentale Abneigung gegenüber StringStreams besitzen.

    "Anstatt" ist allerdings nicht ganz korrekt; man wird, wenn man String-Operationen durchführen will, trotzdem mit den Strings zu tun haben (oder mindestens mit std::stringstream::str() )



  • Ich seh das Problem grad irgendwie auch nicht.

    Ich hab zwar nicht endlos viel java erfahrung(nur was man so in der uni eben macht), aber eigentlich immer, wenn ich ein konstrukt wie string+int sehe, kommt danach mit 99,9% Wahrscheinlichkeit direkt eine ausgabe.

    quasi sowas wie

    int var=...;
    ...
    System.out.println("teststring"+var);
    

    Und in dem Fall seh ich das Problem nicht, einfach

    int i;
    cout<<"teststring"<<var<<endl;
    

    zu verwenden.

    Und in den wenigen Fällen wo das nicht reicht, macht man auch nur einen sehr kleinen Umweg:

    String foo(int i)
    {
        String str="teststring"+i;
        return str;
    }
    
    string foo(int)
    {
        stringstream stream;
        stream<<"teststring"<<i;
        return stream.str();
    }
    

    Natürlich haben beide Implementationen ihre Vorteile. Java ist ein wenig kürzer und, zugegebenermaßen mit weniger benötigtem wissen und denkaufwand verbunden. Dafür ist die C++ Lösung flexibler(lokalisierung! wie wird das btw in java geregelt?)



  • otze schrieb:

    (lokalisierung! wie wird das btw in java geregelt?)

    Schlechter als in C++ imo http://www.math.tu-berlin.de/~felsner/Lehre/ProgMeth/Buecher/Krueger/html/k100115.html



  • camper schrieb:

    .filmor schrieb:

    Kann man ihn vielleicht in einen megakonformen Modus schalten in dem er sowas ablehnt?

    Selbstverständlich gibt es diesen (und ist auch nicht schwer zu finden)- was bedeutet, dass falsch seine Hausaufgaben nicht gemacht hat. Das wiederum war der Grund, warum ich gar nicht erst darauf hingewiesen habe.

    Moment, jetzt mal langsam. Wenn es nach Standard nicht erlaubt ist, dann ist es doch so oder so falsches Verhalten. Ich kenne nur das Warning-Level, wenn ich das jetzt auf 4 stelle, was den höchsten Wert bedeutet, bekomme ich zumindest einen Hinweis auf die Konvertierung zur Referenz:

    Warning	3	warning C4239: nonstandard extension used : 'argument' : conversion from 'std::basic_string<_Elem,_Traits,_Ax>' to 'std::string &'	c:\...\main.cpp	46
    


  • Dreh ihm (dem MSVC Compiler) mal die "Microsoft Extensions" aus, dann meldet er es schon als Fehler, keine Sorge.

    Oder du kannst einzelne Warnings zu Fehlern erklären, z.B. so:

    #pragma warning(error: 4239)
    


  • Ich hab jetzt /Za gesetzt, bei dem Warning bleibt er jetzt stehen. In der MSDN steht aber im Kapitel "Nonstandard Behavior" nichts dazu.


Anmelden zum Antworten