Fehler in g++ oder nicht standardkonformer Code?



  • Hallo,

    folgender Code wird von g++ 3.x einwandfrei kompiliert:

    template <class Type> class Foo
    {
            private:
                    Type m_t;
    
                    Foo( const Foo& ); // Zeile 6
            public:
                    explicit Foo( const Type& t )
                     : m_t(t)
                    {
                    }
    
                    operator Type() const
                    {
                            return m_t;
                    }
    };
    
    template <class A> bool set( const A& value )
    {
            return true;
    }
    
    int main()
    {
            int i = 5;
            Foo<int> foo(i);
    
            set( Foo<int>( (int)foo ) ); // Zeile 30
    }
    

    g++ 4.0 hingegen sagt:

    bla.cc: In function 'int main()':
    bla.cc:6: error: 'Foo<Type>::Foo(const Foo<Type>&) [with Type = int]' is private
    bla.cc:30: error: within this context
    

    Ist nun der g++ kaputt oder der Code?
    Kennt jemand einen Workaround außer eine lokale Variable zu definieren
    und diese dann der set Funktion als Parameter zu übergeben?



  • gcc 4.0 liegt wohl richtig
    Standard 12.2 sagt, dass ein temporäres Objekt benötigt wird um einen rvalue (in Deinem Fall das Foo<int>( (int)foo) an eine Referenz zu binden. Auch wenn dieses Objekt vom Compiler dann eliminiert werden kann, muss der Compiler prüfen, ob es angelegt werden kann. Und das geht in Deinem Fall nicht.

    Temporaries of class type are created in various contexts: binding an rvalue to a reference (8.5.3), returning an rvalue (6.6.3), a conversion that creates an rvalue (4.1, 5.2.9, 5.2.11, 5.4), throwing an exception (15.1), entering a handler (15.3), and in some initializations (8.5). [Note: the lifetime of exception objects is described in 15.1. ] Even when the creation of the temporary object is avoided (12.8), all the semantic restrictions must be respected as if the temporary object was created. [Example: even if the copy constructor is not called, all the semantic restrictions, such as accessibility (clause 11), shall be satisfied. ]
    2 [Example:

    class X {
    // ...
    public:
    // ...
      X(int);
      X(const X&);
      ~X();
    };
    
    X f(X);
    
    void g()
    {
      X a(1);
      X b = f(X(2));
      a = f(a);
    }
    

    Here, an implementation might use a temporary in which to construct X(2) before passing it to f() using X’s copyconstructor;
    alternatively, X(2) might be constructed in the space used to hold the argument.
    Also, a temporary might be used to hold the result of f(X(2)) before copying it to b using X’s copyconstructor;
    alternatively, f()’s result might be constructed in b. On the other hand, the expression a=f(a) requires a temporary for either the argument a or the result of f(a) to avoid undesired aliasing of a]



  • Comeau compiliert es auch nicht. Dein Code ist wohl falsch.



  • eigentlich müsste der code einwandfrei funktionieren und auch mein vc++6 schluckt ihn ohne zu murren *seltsam*



  • Konfusius schrieb:

    eigentlich müsste der code einwandfrei funktionieren und auch mein vc++6 schluckt ihn ohne zu murren *seltsam*

    🤡 👍



  • ign0rant schrieb:

    folgender Code wird von g++ 3.x einwandfrei kompiliert:

    Kann ich nicht bestätigen, zumindest beim 3.4.4.

    Konfusius schrieb:

    eigentlich müsste der code einwandfrei funktionieren und auch mein vc++6 schluckt ihn ohne zu murren *seltsam*

    Nicht raten, nachschlagen...

    ign0rant schrieb:

    Kennt jemand einen Workaround außer eine lokale Variable zu definieren

    Nunja, da dein Code keinen Sinn ergibt, kann ich dazu nicht viel sagen. Vielleicht könntest du mal ein reelles Szenario als Beispielcode posten.



  • groovemaster schrieb:

    Konfusius schrieb:

    eigentlich müsste der code einwandfrei funktionieren und auch mein vc++6 schluckt ihn ohne zu murren *seltsam*

    Nicht raten, nachschlagen...

    nicht raten? ich dachte, es wäre mal ein perfekt getarnter witz 😃



  • Wenn Konfusius statt dem "und auch" einfach ein Komma gemacht hätte, hätte ich ihn glatt durchgehen lassen. 😃


Anmelden zum Antworten