Parameterkette in Funktionssignatur (...)



  • Es ist nicht nur nicht typsicher, wenn es mit C++-Objekten gefüttert wird erzeugt es auch noch undefiniertes Verhalten.
    Es gibt aber einen sehr vielversprechenden Ansatz für eine Spracherweiterung deren Namen mir gerade nicht einfällt, die das ganze dann "ordentlich" über Templates erledigen kann.



  • Erwähnenswert ist noch, dass die Ellipse manchmal beim Überladen ganz praktisch ist, weil sie am schlechtesten auf einen Parametertyp passt.



  • Geht mal in google nach "variadic templates" suchen!!



  • .filmor schrieb:

    Es ist nicht nur nicht typsicher, wenn es mit C++-Objekten gefüttert wird erzeugt es auch noch undefiniertes Verhalten.
    Es gibt aber einen sehr vielversprechenden Ansatz für eine Spracherweiterung deren Namen mir gerade nicht einfällt, die das ganze dann "ordentlich" über Templates erledigen kann.

    variadic templates schimpft sich des sichere

    http://www.osl.iu.edu/~dgregor/cpp/variadic-templates.html



  • ich benutz das aber erst wenn das offiziell ist. Sieht aber schonmal cool aus.



  • r0nny schrieb:

    variadic templates schimpft sich des sichere

    http://www.osl.iu.edu/~dgregor/cpp/variadic-templates.html

    lemonhead schrieb:

    ich benutz das aber erst wenn das offiziell ist. Sieht aber schonmal cool aus.

    EDIT: sieht wie ich finde grässlich aus, aber jedem das Seine 😃

    Bis dahin könnte man doch ein einfaches Template verwenden, und die varargs als z.B. boost::tuple übergeben. Ist zwar nicht gut dokumentiert, aber Boost.Tuple hat ein "head" und ein "tail" member, wobei "head" das erste Element ist, und "tail" das letzte (bzw. eine "get_head" und eine "get_tail" Funktion). Und mit einer spezialisierung auf "boost::tuple<>" kann man die rekursive template instanzierung abbrechen.

    Sollte relativ einfach machbar sein... und funktioniert mit dem heutigen C++ Standard und heute verfügbaren Compilern.



  • Das macht aber nicht das, wofür man es braucht (nämlich variable Anzahl von Parametern).
    Btw., tail ist nicht das letzte Element sondern der Rest des Tupels.



  • Benutz den Preprocessor um dir automatisch überladene Funktionen für bis zu einer geweissen Anzahl Parameter zu generiren. Ist das beste was du mit dem jetztigen Standard hinkriegst.

    Beispiel:

    #include <boost/preprocessor.hpp>
    #include <iostream>
    
    #define OP_SHIFT(z, n, arg)\
      << arg ## n
    #define MY_PRINT(z, n, data)\
      template<BOOST_PP_ENUM_PARAMS(n ,class T)>\
      void my_print(BOOST_PP_ENUM_BINARY_PARAMS(n, const T, &t))\
      {\
        std::cout BOOST_PP_REPEAT_ ## z(n, OP_SHIFT, t) <<std::endl;\
      }
    
    BOOST_PP_REPEAT_FROM_TO(1, 10, MY_PRINT, nil)
    #undef OP_SHIFT
    #undef MY_PRINT
    
    int main(){
      my_print(1, " + ", 3, '=', 1+3);
    }
    


  • @.filmor:
    ja, sorry, natürlich ist tail der Rest, alles bis aufs erste Element halt.
    Und natürlich ist es ein syntaktischer Unterschied, aber ich kann immernoch schreiben

    foo("%s %s %s", boost::make_tuple("sepp", "hugo", "franz"));
    foo("%s", boost::make_tuple("dings"));
    foo("zonk", boost::tuple<>());
    

    Wenn die genaue Syntax zum Aufruf nicht vorgegeben ist, ist das ein möglicher ersatz. Wenn man natürlich darauf besteht dass foo selbst (und nicht make_tuple) eine variable Anzahl an Parametern frisst ist es kein Ersatz.



  • Du könntest es folgendermasen machen:

    template<class Tuple>
    void foo_impl(const Tuple&){
    
    }
    MAKE_VAR_FUNC(foo)
    

    MAKE_VAR_FUNC würde die nötigen Überladungen erzeugen und alle Parameter als Tuple an foo_impl weiterleiten. Man könnte auch noch ein zusätzlicher Makroparameter einbauen um normale Parameter zu erlauben.

    Da MAKE_VAR_FUNC O(n) ist wo n die maximale Anzahl der Parameter ist wäre könnte man diesen Wert locker auf irgend einen hohen Wert setzen.

    Würde doch in etwa das rauskommen was da versucht wurde als Sprachelement nachzubauen, oder?


Anmelden zum Antworten