Variable in if definieren



  • Hallo!

    Warum geht das hier nur mit einfachen Datentypen, nicht aber zB. mit iteratoren?

    // Möchte Variable gleich im if definieren...
    if(unsigned a = GetValue())
    	cout << "a ist nicht null, sondern: " << a << endl; // ...und hier weiteren Aufruf von GetValue() sparen, besonders wenn man a noch mehrmals braucht
    else
    	cout << "a ist null" << endl;
    


  • Ah sorry, ich mein es zB. so:

    if((std::set<MyClass>::iterator myObject = objects.find(123)) != objects.end())
        ...
    

    Das geht nicht...



  • Definierer schrieb:

    Das geht nicht...

    ... ist eine sehr informative Fehlermeldung...

    mal abgesehen davon machst du nicht das gleiche: bei der ersten Verison ist die erzeugte Variable selbst die Kondition, also in kurz if (a) , beim zweiten Mal ist die Kondition der Vergleich der erzeugten Variablen mit einem anderen Wert. IIRC würde folgendes also auch nicht funktionieren:

    if ((unsigned a = GetValue()) != 1)
    

    ein Workaround wäre folgendes:

    {
      std::set<MyClass>::iterator myObject = objects.find(123);
      if (myObject != objects.end())
      {
      }
      else
      {
      }
    }
    

    Ich meine mal gelesen zu haben, dass der Komma-Operator in if-Konditionen nicht erlaubt ist, falls doch, wäre folgendes auch eine Möglichkeit:

    if (std::set<MyClass>::iterator myObject(objects.find(123)), myObject != objects.end())
    


  • pumuckl schrieb:

    Ich meine mal gelesen zu haben, dass der Komma-Operator in if-Konditionen nicht erlaubt ist, falls doch, wäre folgendes auch eine Möglichkeit:

    if (std::set<MyClass>::iterator myObject(objects.find(123)), myObject != objects.end())
    

    Komma-Operator geht. Der rechte Teil wird ausgewertet. Allerdings kannst du kein Objekt im if statement erzeugen.



  • pumuckl schrieb:

    ...IIRC würde folgendes also auch nicht funktionieren:

    if ((unsigned a = GetValue()) != 1)
    

    ...

    Das Ergebnis einer Deklaration einer benannten Variable scheint ja nicht die Variable selbst zu sein.
    Wobei mich das schon ein wenig verwundert, weil das bei "unbenannten Objekten" funktioniert.

    struct B {
       int i;
       B() : i(3) {}
       operator int() { return i; }
    };
    
    int main() {
       if(B() == 3) cout << "if1\n"; // OK
       if((B b) == 3) cout << "if2\n"; // "main.cpp", line 40.10: 1540-0063 (S) The text "b" is unexpected.
    
       return 0;
    }
    

    (xlC V.5)

    drakon schrieb:

    ...Allerdings kannst du kein Objekt im if statement erzeugen.

    hmmmm - steht das im Std irgendwo?
    Implizit machen wir das doch überall:

    if(atoi("2") == 2) ...
    

    erzeugt doch auch ein int im if ... und ich bin ziemlich sicher, dass das mit std::sting und allen andern Objekten auch "geht"...
    Mein Verdacht halt: Sobald ein "Name" ins Spiel kommt, weiß der Compiler nicht, was er damit machen soll...

    Gruß,

    Simon2.

    Gruß,

    Simon2.



  • Simon2 schrieb:

    pumuckl schrieb:

    ...IIRC würde folgendes also auch nicht funktionieren:

    if ((unsigned a = GetValue()) != 1)
    

    ...

    Das Ergebnis einer Deklaration einer benannten Variable scheint ja nicht die Variable selbst zu sein.
    Wobei mich das schon ein wenig verwundert, weil das bei "unbenannten Objekten" funktioniert.

    B() ist ein temporäres Objekt, während B b eine Dekleration ist..

    erzeugt doch auch ein int im if ... und ich bin ziemlich sicher, dass das mit std::sting und allen andern Objekten auch "geht"...
    Mein Verdacht halt: Sobald ein "Name" ins Spiel kommt, weiß der Compiler nicht, was er damit machen soll...

    Ja. Erzeugung von tempoären Objekten ist erlaubt.

    (Siehe 12.2)



  • drakon schrieb:

    ...B() ist ein temporäres Objekt, während B b eine Dekleration ist...

    Ich hatte das statement "B()" in dem Zusammenhang immer als "Deklaration eines temporären und unbenannten Objekts" aufgefasst.

    Gruß,

    Simon2.



  • B() ist ein Ausdruck. Deklarationen sind keine Ausdrücke.



  • Bashar schrieb:

    B() ist ein Ausdruck. Deklarationen sind keine Ausdrücke.

    💡 Aha!

    Darüber muss ich noch ein wenig meditieren. Ich merke gerade, dass ich mir über den Begriff "Ausdruck" noch nicht ausreichend Gedanken gemacht habe.

    Danke,

    Simon2.



  • Stimmt, das hier geht nicht...

    if((unsigned a = GetValue()) != 0)
    		cout << "a ist nicht null, sondern: " << a << endl;
    	else
    		cout << "a ist null" << endl;
    

    Find ich schon sehr schade und verstehe noch immer nicht warum das so ist.
    Wenn "if(unsigned a = 3)" gültig ist, sollte "if((unsigned a = 3) != 0)" es auch sein...

    Wenn "unsigned a = 3" kein Ausdruck ist, warum darf es dann im ' if ' stehen?
    Ich habe gelernt:

    "Der Wert einer Zuweisung ist der zugewiesene Wert".

    Demnach wäre "if((unsigned a = 3) != 0)" doch gleichzusetzen mit "if((3) != 0)".

    Nunja, dies ist halt auch eine Definition, aber wenn es doch kein Ausdruck ist?

    😕



  • Es handelt sich dabei aber nicht um eine Zuweisung sondern um eine Definition:

    int a = 5; //Definition
    a = 6; //Zuweisung
    


  • Ja, aber hier doch auch:

    if(unsigned a = GetValue())
    ...

    Und wenn die (anscheinend) einen boolsche Wert sein kann, so sollte es hier auch so sein:

    if((unsigned a = GetValue()) != 0)
    ...



  • Dass Deklarationen im Kopf von if-Anweisungen (bei while und switch m.W. auch) stehen dürfen ist ein Sonderfall. Daraus kann man nicht ableiten, dass das Ausdrücke sind, die man irgendwie anders noch verwenden könnte.


Anmelden zum Antworten