code standardgemäs?



  • hi

    kann sich irgend ein erfahrener user diesen code anschauen?

    #include <iostream>
    class container
    {
      float val;
      public:
        container(float value):val(value){}
        operator float&()
        {return val;}
        operator float() const
        {return val;}
    };
    class access;
    access foo(container&);
    const access foo(const container&);
    class access
    {
      friend access foo(container&);
      friend const access foo(const container&);
      explicit access(float& target, float mult = 1.0f)
      : target(target)
      {
        this->mult = mult;
      }
      float& target;
      float mult;
      public:
        access& operator= (float value)
        {
          target = value * mult;
          return *this;
        }
        operator float&()
        {
          return target;
        }
        operator const float() const
        {
          return target / mult;
        }
    };
    access foo(container& data)
    {
      return access(static_cast<float&>(data), 10.0f);
    }
    const access foo(const container& data)
    {
      return access(static_cast<float&>(const_cast<container&>(data)), 10.0f);
    }
    int main()
    {
      container data = 3.0f;
      foo(data) = 0.5f; //data sollte nun 50 sein
      std::cout << foo(data); //sollte 5 ausgeben
    }
    

    ich versuchte ihn bei vier compilern:
    gcc 4.3.4 fail
    codegear c++ builder fail
    visual c++ 2008 good
    comeau c++ 4.3.9 good

    bitte helft mir
    danke im vorraus
    mfg



  • lol_of_lolcraft schrieb:

    hi

    kann sich irgend ein erfahrener user diesen code anschauen?

    Klar. Erledigt.

    Vielleicht fehlt noch eine Frage deinerseits, und die Compilerfehlermeldung an Stelle eines "fail" wäre klasse. Siehe auch Link in meiner Signatur.



  • na ist der code nun standardgemäs?
    gcc mault:

    prog.cpp:13: error: ‘access’ does not name a type
    prog.cpp:14: error: ‘access’ does not name a type
    prog.cpp:41: error: ‘access’ does not name a type
    prog.cpp:45: error: ‘access’ does not name a type
    prog.cpp: In function ‘int main()’:
    prog.cpp:52: error: ‘foo’ was not declared in this scope

    und codegear mault wegen mehrdeutigkeit in zeile 53.


  • Mod

    So komisch das klingen mag: Wenn ich die Klasse anders nenne funktioniert es. Aber frag mich nicht warum, ich kenne kein Schlüsselwort, das so heißt.



  • 😃 Mann, was läuft denn da ab?



  • SeppJ schrieb:

    So komisch das klingen mag: Wenn ich die Klasse anders nenne funktioniert es. Aber frag mich nicht warum, ich kenne kein Schlüsselwort, das so heißt.

    Scheint so, als gäbs das Problem schon länger. In deinem Fall wahrscheinlich ein Problem mit access(), das aus einem Header automatisch eingebunden und in den globalen Namensraum gestellt wird.



  • Für das gibt's namespaces.



  • und wieso gibt codegear c++ builder einen fehler aus? er kann sich nicht zwischen den beiden ausgabeoperatoren (double, long double) entscheiden. wenn ich den konstanten konvertierungsoperator entferne gehts.


  • Mod

    lol_of_lolcraft schrieb:

    und wieso gibt codegear c++ builder einen fehler aus? er kann sich nicht zwischen den beiden ausgabeoperatoren (double, long double) entscheiden. wenn ich den konstanten konvertierungsoperator entferne gehts.

    Welche doubles und long doubles denn jetzt? Ich sehe überall nur floats. Und was sagt er genau?

    Nexus schrieb:

    SeppJ schrieb:

    So komisch das klingen mag: Wenn ich die Klasse anders nenne funktioniert es. Aber frag mich nicht warum, ich kenne kein Schlüsselwort, das so heißt.

    Scheint so, als gäbs das Problem schon länger. In deinem Fall wahrscheinlich ein Problem mit access(), das aus einem Header automatisch eingebunden und in den globalen Namensraum gestellt wird.

    Ach nö. 😡 Das ist ja wohl nicht wahr. Ist das eigentlich vom Standard erlaubt, dass die Implementierung den globalen Namensraum verseucht (Abgesehen von reservierten Bezeichnern)? Und dazu dann noch so eine unklare Fehlermeldung. Ein Fehler der auf eine widersprüchliche Deklaration hinweist hätte alles sofort klar gemacht.


  • Mod

    SeppJ schrieb:

    lol_of_lolcraft schrieb:

    und wieso gibt codegear c++ builder einen fehler aus? er kann sich nicht zwischen den beiden ausgabeoperatoren (double, long double) entscheiden. wenn ich den konstanten konvertierungsoperator entferne gehts.

    Welche doubles und long doubles denn jetzt? Ich sehe überall nur floats. Und was sagt er genau?

    Nexus schrieb:

    SeppJ schrieb:

    So komisch das klingen mag: Wenn ich die Klasse anders nenne funktioniert es. Aber frag mich nicht warum, ich kenne kein Schlüsselwort, das so heißt.

    Scheint so, als gäbs das Problem schon länger. In deinem Fall wahrscheinlich ein Problem mit access(), das aus einem Header automatisch eingebunden und in den globalen Namensraum gestellt wird.

    Ach nö. 😡 Das ist ja wohl nicht wahr. Ist das eigentlich vom Standard erlaubt, dass die Implementierung den globalen Namensraum verseucht (Abgesehen von reservierten Bezeichnern)? Und dazu dann noch so eine unklare Fehlermeldung. Ein Fehler der auf eine widersprüchliche Deklaration hinweist hätte alles sofort klar gemacht.

    Mit C++0x wird es vermutlich besser werden, ich denke genau aus diesem Grund ist der Namensraum posix dann reserviert (hab mir das paper dazu aber nicht angesehen). Dann soll offenbar der Ganze posix Kram in diesn Namensraum wandern. Bevor es soweit ist, werden wir wohl mit derartigen Verschmutzungen rechnen müssen... aber der globale Namensraum war da ja schon immer anfällig. Das Ganze im gcc von jetzt auf gleich zu korrigieren dürfte vermutlich mit einem Mal eine gewaltige Menge an Code kaputtmachen, also vermute ich mal, dass das nach und nach passiert, so wie in der Vergangenheit die Standardheader mit jeder Version mehr entrümpelt wurden.



  • SeppJ schrieb:

    Ach nö. 😡 Das ist ja wohl nicht wahr. Ist das eigentlich vom Standard erlaubt, dass die Implementierung den globalen Namensraum verseucht (Abgesehen von reservierten Bezeichnern)? Und dazu dann noch so eine unklare Fehlermeldung. Ein Fehler der auf eine widersprüchliche Deklaration hinweist hätte alles sofort klar gemacht.

    Der Standard enthält dazu keine explizite Regelung, man kann höchstens aus der Existenz reservierter Bezeichner herauslesen, dass solche Verschmutzung nicht gewollt ist. In der Praxis muss man allerdings damit rechnen, dass so etwas passiert bzw. man ein paar Schrauben drehen muss, um es zu verhindern.

    Konkret versucht gcc, es zu verhindern, wenn auf der Kommandozeile -ansi übergeben wird; das führt dazu, dass verschiedene __USE-Makros nicht definiert werden und glibc große Teile von Headerdateien auslässt. Ich vermute, dass es in diesem konkreten Fall das Problem lösen dürfte.

    Trotzdem wäre die Benutzung eines eigenen Namensraumes eine gute Idee.


Anmelden zum Antworten