[gelöst] Warum wird hier ein Standard-ctor benötigt?



  • Hallo zusammen,

    folgende Frage:

    #include <map>
    
    class Foo
    {
        public:
            Foo(int id) : id(id){}
            int getId() const
            {
                return id;
            }
    
        private:
            int id;
    };
    
    class Foos
    {
        public:
    
            void addFoo(const Foo& foo)
            {
                foos[foo.getId()] = foo;
            }
    
        private:
    
            std::map<int, Foo> foos;
    };
    
    int main(int argc, char *argv[])
    {
        Foo f1{1};
        Foo f2{2};
        Foo f3{3};
    
        Foos foos;
        foos.addFoo(f1);
        foos.addFoo(f2);
        foos.addFoo(f3);
    
        return 0;
    }
    

    Mit diesem Code erhalte ich folgende Meldung:

    Fehler: no matching function for call to 'Foo::Foo()'
    second(std::forward<_Args2>(std::get<_Indexes2>(__tuple2))...)

    Sobald ich einen leeren Standard-ctor für "Foo" spendiere funktioniert es.

    Warum ist das so?
    Bringt der leere ctor irgendwelche Nachteile?
    Gibt es eine andere Lösung?

    Danke,
    temi


  • Mod

    Das Problem ist deine falsche Nutzung von map. Der map::operator[] braucht einen Standardkonstruktor, da es einfach das definierte Verhalten dieses Operators ist, im Falle eines nicht gefundenen Schlüssels, en standardkonstruiertes Element an der Stelle einzufügen. Du möchtest wahrscheinlich lieber map::insert benutzen, das entspricht besser der Semantik, die du dir vorstellst.

    An sich zum Thema sinnloser Standardkonstruktoren: Sie sind sinnlos 🙂
    Wenn es keine sinnvolle Standardkonstruktion einer Klasse gibt, dann wäre es Selbsttäuschung diese anzubieten. Der Standardkonstruktor wird schließlich nur benötigt, wenn er auch benutzt wird. Und wenn es aber keine sinnvolle Standardkonstruktion gibt, dann war diese Benutzung wohl falsch, so wie bei deinem map-Beispiel hier, wo der Code was ganz anderes machte als der Programmierer wollte.



  • Ah, danke!

    Ich hab mir grade noch mal die Doku zur map durchgelesen, ist nicht so ganz augenfällig beschrieben, aber irgendwie ist es logisch, dass um eine Referenz auf ein Objekt zurückzuliefern, dieses Objekt auch erzeugt werden muss.

    Mein Code hat demnach (mit "sinnlosem" ctor) zuerst ein "leeres" Objekt erzeugt und dieses anschließend überschrieben.


Anmelden zum Antworten