Variadic Function ohne Parameteranzahl



  • Wurstinator schrieb:

    Also ein echter Array ist ein solcher, bei dem der Compiler die Größe kennt?

    Ja

    void funktion(int array[]); // ein Zeiger
    void funktion(int array[3]); // ein Array?
    

    Nein - das gehört zu den Erbschaften von C, daß hier die Größenangabe nicht beachtet wird und biede Funktionen einen Zeiger übergeben bekommen.



  • Manchmal mag man die Erbschaft so umgehen:

    template<unsigned int DIM, class VTYPE>
    Vektor<DIM, VTYPE>::Vektor(VTYPE (&vals)[DIM])//nur aufrufbar, wenn die Größe stimmt
    {
        memcpy(values, vals, sizeof(vals));//dann klappt's auch mit dem sizeof
    }
    


  • Oder man umgeht sie einfach, indem man keine Arrays benutzt. 💡



  • Nexus schrieb:

    Oder man umgeht sie einfach, indem man keine Arrays benutzt. 💡

    Erbschaft umgehen? Du solltest Dir eine andere Programmiersprache suchen!



  • Olga schrieb:

    Nexus schrieb:

    Oder man umgeht sie einfach, indem man keine Arrays benutzt. 💡

    Erbschaft umgehen? Du solltest Dir eine andere Programmiersprache suchen!

    Es gibt auch eine C++-Schule, die anfängt mit
    std::string filename("autoexec.bat");
    und nullterminierte char-arrays außerhalb string-Initialisierungen leugnet.
    Ich bin kein Freund davon. Aber es klappt. Und ist auch in vielerlei Hinsicht schneller, als zu fast allen Sprachen zu wechseln, die Strings als Sprachbestandteil haben.



  • Gewisse C-spezifische Dinge bringts schon. Zeiger und Makros zum Beispiel (ja, Makros). Aber bei Arrays, wo wir mit std::array die gleiche Funktionalität viel besser verpackt haben (Wertsemantik, keine implizite Zeiger-Konvertierung, STL-Interface, Assertions für Indexzugriff), sehe ich keinen Grund, an Antikem festzuhalten.



  • Und wie soll ich einen std::tr1::array als Parameter übergeben, wenn die Arraygröße variabel sein soll?



  • Wurstinator schrieb:

    Und wie soll ich einen std::tr1::array als Parameter übergeben, wenn die Arraygröße variabel sein soll?

    Mach die Funktion halt eben zu einer Template-Funktion.



  • Vektor<5, double> i<3>(array);
    

    Das will ich dem Nutzer (was eigentlich nur ich sein werde) nicht antun 😃



  • Wurstinator schrieb:

    Vektor<5, double> i<3>(array);
    

    Das will ich dem Nutzer (was eigentlich nur ich sein werde) nicht antun 😃

    Was soll das darstellen?



  • Shade Of Mine schrieb:

    Wurstinator schrieb:

    Vektor<5, double> i<3>(array);
    

    Das will ich dem Nutzer (was eigentlich nur ich sein werde) nicht antun 😃

    Was soll das darstellen?

    Einen Fehler. Er will sich selbst keine Fehler antun.



  • Shade Of Mine schrieb:

    Wurstinator schrieb:

    Vektor<5, double> i<3>(array);
    

    Das will ich dem Nutzer (was eigentlich nur ich sein werde) nicht antun 😃

    Was soll das darstellen?

    Den Konstruktor?!
    Ich hab es nur kurz gegooglet und nicht ausprobiert; wenn es falsch ist, hättest du mir ja einfach die richtige Variante sagen können.



  • Wurstinator schrieb:

    wenn es falsch ist, hättest du mir ja einfach die richtige Variante sagen können.

    Also ich könnte es nicht. Ich kann zwar Template-Konstruktoren definieren, aber ich weiß nicht, wie man sie explizit aufruft. Geht das überhaupt?

    #include <iostream>
    
    struct Foo{
        template<typename T>
        Foo(T t){
            std::cout<<sizeof(T)<<' '<<t<<'\n';
        }
    };
    
    int main()
    {
        Foo f1('a');
        Foo f2(3.14);
        <short>Foo f3(5);//??
        Foo<short> f3(5);//??
        Foo f3<short>(5);//??
        Foo f3(5)<short>;//??
    }
    


  • volkard schrieb:

    Geht das überhaupt?

    Nein, bei Template-Konstruktoren müssen die Templateparameter aus den Funktionsargumenten hergeleitet werden können.



  • Achso, der Compiler schließt also automatisch auf die Größe des Arrays? Das ist ja nett 🙂

    Und was war jetzt hiermit:

    non-POD + ellipse ist sowieso UB.

    Wieso sorgt das für "UB"?



  • Wurstinator schrieb:

    Wieso sorgt das für "UB"?

    Weil die variable Argumentliste ein C-Sprachmittel ist, das nicht auf die Kopiersemantik von Klassen ausgelegt worden ist. Kopierkonstruktor etc. werden also nicht aufgerufen. Ähnlich wie wenn du versuchst, Klassen mit memcpy() zu kopieren.



  • Hm, okay.
    Aber ich hab die Methoden ja jetzt so geändert, dass die Elemente mit dem Zuweisungsoperator in den Array eingefügt werden. Somit sollte das doch fehlerfrei gehen, oder nicht?



  • Hi,
    kann mir jemand erklären, was dieser Teil aus der "fertigen" Vektor-Klasse macht ?

    template<unsigned int DIM, class VTYPE>
    template<class any>
    Vektor<DIM, VTYPE>::Vektor(any* x, ...)
    {
        va_list args;
        va_start(args, x);
        for (unsigned int n = 0; n < DIM; n++)
            values[n] = va_arg(args, VTYPE);
        va_end(args);
    }
    

    Gruss



  • Was genau meinst du?
    Der Konstruktor nimmt eine beliebige Anzahl von Parametern und nimmt diese dann als Vektor-Werte.


Anmelden zum Antworten