no suitable constructor exists



  • Hallo,
    ich habe gerade das Gefühl, das ich was auf den Kopf bekommen habe. Ich habe eine Klasse und eine struct, die für mich das selbe beinhalten. Allerdings kann ich die struct Triangle nicht auf die selbe Weise füttern.

    class Vector3Dc
    {
    public:
    	int x = 0;
    	int y = 0;
    	int z = 0;
    	int w = 1;
    
    public:
    	Vector3Dc() = default;
    	Vector3Dc(const int x, const int y, const int z) : x(x), y(y), z(z), w(1) {}
    	Vector3Dc(const Vector3Dc& vec3D) : x(vec3D.x), y(vec3D.y), z(vec3D.z), w(vec3D.w) {}
    };
    
    struct Vector3Ds
    {
    	int x = 0;
    	int y = 0;
    	int z = 0;
    };
    
    //using Vec = Vector3Dc;
    using Vec = Vector3Ds;
    
    struct Triangle
    {
    	Vec p[3];
    };
    
    int main()
    {
    	Vec vec1 = { 1, 1, 1 };
    	Vec vec2 = { 2, 2, 2 };
    	Vec vec3 = { 3, 3, 3 };
    	Triangle tri1 = { vec1, vec2, vec3 }; // ok in beiden Versionen
    	Triangle tri2 = { 1, 1, 1, 2, 2, 2, 3, 3, 3 }; // nur mit struct ok, sonst E0415: no suitable constructor exists to convert from "int" to "Vector3Dc"
            //Triangle tri3 = { { 1, 1, 1 }, { 2, 2, 2 }, { 3, 3, 3 } }; // fehler in beiden Versionen E0146: too many initializer values
    }
    

    Hoffentlich wird es durch die Kommentare ersichtlich, was ich meine. Ich habe die schlimme Befürchtung, das ich was ganz doofes einfaches übersehe oder nicht verstehe.



  • Das Array in Triangle brauch auch nochmal {}:

        Triangle tri3 = { { { 1, 1, 1 }, { 2, 2, 2 }, { 3, 3, 3 } } };
    

    Und dass { 1, 1, 1, 2, 2, 2, 3, 3, 3 } nicht geht sollte auch klar sein. Das ist nur für so triviales POD-gedöns erlaubt (ich glaube die korrekte Bezeichnung ist aggregate.)

    Und sobald deine Klasse bzw. eine ihrer Basisklassen oder ein Member irgend einen Konstruktor definiert, ist deine Klasse halt kein aggregate mehr.



  • @hustbaer sagte in no suitable constructor exists:

    Das Array in Triangle brauch auch nochmal {}:

        Triangle tri3 = { { { 1, 1, 1 }, { 2, 2, 2 }, { 3, 3, 3 } } };
    

    Und sobald deine Klasse bzw. eine ihrer Basisklassen oder ein Member irgend einen Konstruktor definiert, ist deine Klasse halt kein aggregate mehr.

    Ah, danke... 😌



  • @zeropage sagte in no suitable constructor exists:

    Hallo,
    ich habe gerade das Gefühl, das ich was auf den Kopf bekommen habe. Ich habe eine Klasse und eine struct, die für mich das selbe beinhalten. Allerdings kann ich die struct Triangle nicht auf die selbe Weise füttern.

    class Vector3Dc
    {
    public:
    	int x = 0;
    	int y = 0;
    	int z = 0;
    	int w = 1;
    

    Was soll das?

    Wenn man Werte für Member explizit setzen will, schreibt man einen Default Constructor. Da bei Dir alles public ist macht es keinen Sinn hier eine class zu nehmen, es ist in C++ vollkommen egal, ob man struct oder class nutzt, das bezieht sich nur darauf, public oder private als Vorgabe für die Member Vorgabe ist. POD oder nicht entscheidet sich nicht durch das Schlüsselwort.

    // CC ist default, den braucht man hier nicht zu implementieren
    
    struct Vector3Dc {
        int x, y, z, w;
    
        Vector3Dc (const int xx, const int yy, const int zz) : x(xx), y(yy), z(zz), w(1) {}
        Vector3Dc () : Vector3Dc (0, 0, 0) {}
    };
    

    Den Rest hat hustbaer schon erklärt.



  • @john-0 sagte in no suitable constructor exists:

    Wenn man Werte für Member explizit setzen will, schreibt man einen Default Constructor.

    Das schöne ist doch, dass man das nicht mehr muss, weil mir der Compiler das abnimmt. Und @zeropage könnte sogar w(1) im Custom Ctor weglassen und es würde alles funktionieren und wäre richtig initialisiert.

    Die Frage ist doch eher, warum da ein Copy Ctor von Hand geschrieben wird? Auch den gibt mir der Compiler frei haus.

    Edit: Ah, den Copy Ctor hast du im Kommentar erwähnt, dass hab ich irgendwie übersehen.



  • @john-0 sagte in no suitable constructor exists:

    Was soll das?

    Member initialisieren

    Wenn man Werte für Member explizit setzen will, schreibt man einen Default Constructor.

    Nö, wozu?



  • @Schlangenmensch sagte in no suitable constructor exists:

    Das schöne ist doch, dass man das nicht mehr muss, weil mir der Compiler das abnimmt.

    Der Punkt ist, ist das sinnvoll? Letztlich wird so oder so Konstruktor aufgerufen, und im konkreten Fall wird der Code kompakter und besser lesbar, wenn man das mit einen expliziten Konstruktor macht. Man sollte nie vergessen, dass nicht jeder zu 100% mit den Besonderheiten einer Sprache vertraut ist.



  • @john-0 Ich finde das sinnvoll. Wenn ich zum Beispiel einen Member immer gleich initialisieren möchte, aber mehrere Ctors habe, muss ich das z.B. nicht immer mit schreiben.
    Oder ich kann einfach aus der IDE zur Member Deklaration springen und sehe direkt den Default Wert. Also, wie gesagt, ich finde das sinnvoll.

    Was Programmierer betrifft, die von anderen Sprachen kommen: Java zum Beispiel unterstützt das auch und C# soweit ich weiß auch. Damit ist das jetzt nicht wirklich ein C++ Spezialfall.



  • @john-0 sagte in no suitable constructor exists:
    ...

    Was soll das?

    Wenn man Werte für Member explizit setzen will, schreibt man einen Default Constructor. Da bei Dir alles public ist macht es keinen Sinn hier eine class zu nehmen, es ist in C++ vollkommen egal, ob man struct oder class nutzt, das bezieht sich nur darauf, public oder private als Vorgabe für die Member Vorgabe ist. POD oder nicht entscheidet sich nicht durch das Schlüsselwort.
    ...

    Aber wenn´s doch egal ist, dann kann man doch struct oder class nehmen, je nach eigenem gusto.

    Edit:
    Ich bin auch dazu übergegangen, Member schon im Header zu initialisieren. Damit hat man beim Angucken der Klasse schon einen Überblick, was die Standardwerte sind.



  • @john-0 sagte in no suitable constructor exists:

    @Schlangenmensch sagte in no suitable constructor exists:

    Das schöne ist doch, dass man das nicht mehr muss, weil mir der Compiler das abnimmt.

    Der Punkt ist, ist das sinnvoll?

    Sogar sehr sinnvoll!



  • Auch wenn ich nicht mehr antworte, ich lese immer fleißig mit. 😉



  • PS: Normalerweise sind meine Member private und ich stelle sie gerne nach oben, damit ich sofort sehe, was da vorkommt. Diesmal sind sie public, aber deshalb stelle ich nicht die ganze Klasse um oder ändere sie zu einer struct. Stattdessen ändere ich nur das Schlüsselwort. Außerdem war es ein "minimal kompilierbares Beispiel" (auch wenn nicht vollständig minimalisiert), es gibt noch private Methoden.
    Und wenns egal ist, kanns nicht falsch sein... 😇


Anmelden zum Antworten