Array an Funktion mit variabler Argumentenliste übergeben



  • void foo(int a, ...);
    int ia[] = {1, 2, 3, 4, 5};
    foo(2, ia);
    

    Ich verstehe dein Problem nicht.



  • nwp3 schrieb:

    void foo(int a, ...);
    int ia[] = {1, 2, 3, 4, 5};
    foo(2, ia);
    

    Ich verstehe dein Problem nicht.

    Er redet von einer variablen Anzahl an Argumenten, wobei er sich auf der C-Schiene bewegt.



  • nwp3 schrieb:

    void foo(int a, ...);
    int ia[] = {1, 2, 3, 4, 5};
    foo(2, ia);
    

    Ich verstehe dein Problem nicht.

    Bei mir funtioniert das nicht:

    #include <cstdarg>
    #include <iostream>
    using namespace std;
    
    void foo(int count, ...)
    {
      va_list list;
      va_start(list, count);
      for(int c = 0; c < count; c++)
        std::cout << va_arg(list, int) << " ";
      va_end(list);
     std:cout << std::endl;
    
    }
    
    int main()
    {
      int ints[] = {1, 2, 3, 4};
      foo(4, ints);
      foo(4, 5, 6, 7, 8);
      return 0;
    }
    
    $ g++ tmp.cpp && ./a.out 
    -1157254800 -1157254536 4 -1233998720
    5 6 7 8
    


  • Ich bin nicht wirklich fitt in variadic templates . Aber ich glaube, das ist das, was du willst?

    #include <array>
    #include <iostream>
    using namespace std;
    
    template<size_t N>
    void foo( const array<int,N>& ar )
    {
    	for(const auto value : ar)
    		cout << value << " ";
    }
    
    template<typename T>
    void foo( T value )
    {
    	cout << value << " ";
    }
    
    template<typename T, typename... Args>
    void foo( T value, Args... args )
    {
    	cout << value << " ";
    	foo( args... );
    }
    
    int main()
    {
    	array<int,4> ints = {{5,6,7,8}};
    
    	foo( ints );
    	cout << '\n';
    	foo( 5, 6, 7, 8 );
    }
    


  • Das Problem ist, dass die variadic function nicht von mir geschrieben, sondern Teil einer Bibliothek ist ( wl_proxy_marshal in libwayland um genau zu sein). Daher kann ich diese nicht verändern. 😞



  • Sieh dir mal das hier an, erster Treffer beim Suchen von "C variadic function":
    http://www.gnu.org/software/libc/manual/html_node/Variadic-Example.html#Variadic-Example



  • Evoli schrieb:

    Kann ich einer Funktion mit variabler Argumentenliste (z.B. void foo(int a, ...) ) irgrandwie ein Array mit Integern übergeben?

    Ja. Kann man.
    Dann werden aber auch nur 2 Argumente übergeben/ausgewertet, und nicht die Elemente des 2. Arguments (Array) einzeln als int, was du wohl erreichen möchtest.



  • nwp3 schrieb:

    Sieh dir mal das hier an, erster Treffer beim Suchen von "C variadic function":
    http://www.gnu.org/software/libc/manual/html_node/Variadic-Example.html#Variadic-Example

    Ich sehe dort keine variadic function, der ein array übergeben wird. Lediglich ein gewöhnlicher veriadic function call...

    Wutz schrieb:

    Evoli schrieb:

    Kann ich einer Funktion mit variabler Argumentenliste (z.B. void foo(int a, ...) ) irgrandwie ein Array mit Integern übergeben?

    Ja. Kann man.
    Dann werden aber auch nur 2 Argumente übergeben/ausgewertet, und nicht die Elemente des 2. Arguments (Array) einzeln als int, was du wohl erreichen möchtest.

    Schade. 😞



  • Folgendes sollte so ziemlich auf jeder Plattform gehen:

    void foo(int count, ...)
    {
      va_list list;
      va_start(list, count);
      for(int c = 0; c < count; c++)
        std::cout << va_arg(list, int) << " ";
      va_end(list);
      std::cout << std::endl; 
    }
    
    struct std_array {
      int ints[4]; // 4 oder eine beliebige andere Zahl. Muss aber konstant sein
    };
    
    int main()
    {
      int ints[] = {1, 2, 3, 4};
      std_array s; std::memcpy(static_cast<void*>(&s),ints,sizeof(s));
      foo(4, s);
      foo(4, 5, 6, 7, 8);
      return 0;
    }
    


  • Sorry erstmal, das ich solange nicht geantwortet habe 😃
    Also nach dem neuen C++11, sind variable Parameteranzahlen möglich:
    (Der Code ist unordentlich und sollte so nicht verwendet werden, aber er funktioniert 😃 )

    #include <iostream>
    
    template<typename ... T>
    void function(int* a, T ... rest)
    {
    a[2]=100000;
    
    }
    
    int main()
    {
    
        int b[10]={1,2,3,4,5,6,7,8,9,10};
    	std::cout << "Davor:" << std::endl;
    	for(int i = 0; i<10 ;i++)
    	{
    	std::cout << b[i] << std::endl;
    	}
    	std::cout << std::endl << "Danach:" << std::endl;
    	function(b,12,"a",12.0f);
    	for(int i = 0; i<10 ;i++)
    	{
    	std::cout << b[i] << std::endl;
    	}
    	std::cin.get();
    
    }
    


  • hntqegafs schrieb:

    Folgendes sollte so ziemlich auf jeder Plattform gehen:
    (...)

    Bei mir kommt da

    $ ./a.out 
    1 3 4197020 -1211368256 
    5 6 7 8
    

    raus. Gcc 4.8, Linux x86-64.

    Folgendes ginge:

    #include <cstdarg>
    #include <type_traits>
    #include <functional>
    #include <iostream>
    
    void foo(int count, ...)
    {
      va_list list;
      va_start(list, count);
      for(int c = 0; c < count; c++)
        std::cout << va_arg(list, int) << " ";
      va_end(list);
      std::cout << std::endl;
    }
    
    // std::result_of kann mit variadischen Funktionen leider nicht umgehen, also
    // muss man das einmal selbst machen.
    template<typename F> struct variadic_result_of;
    template<typename R, typename... Args> struct variadic_result_of<R(Args..., ...)> {
      typedef R type;
    };
    
    template<typename R, typename... Args> struct variadic_result_of<R(*)(Args..., ...)> {
      typedef R type;
    };
    
    // Funktionsaufruf zusammensetzen.
    template<std::size_t N> struct variadic_call_helper {
      template<typename F, typename T, typename... Args>
      static typename variadic_result_of<F>::type call(F func, T *data, Args&&... args) {
        return variadic_call_helper<N - 1>::call(func, data + 1, args..., *data);
      }
    };
    
    // Wenn fertig: aufrufen.
    template<> struct variadic_call_helper<0> {
      template<typename F, typename T, typename... Args>
      static typename variadic_result_of<F>::type call(F func, T*, Args&&... args) {
        return func(args...);
      }
    };
    
    template<typename F, typename T, std::size_t N, typename... Args>
    typename variadic_result_of<F>::type call_variadic_function(F func, T (&arr)[N], Args&&... args) {
      return variadic_call_helper<N>::call(func, arr, std::forward<Args>(args)...);
    }
    
    int main()
    {
      int ints[] = {1, 2, 3, 4};
      // Aufruf etwas verdreht; alle Parameter nach ints werden im Aufruf von
      // foo vor den Arrayinhalt gestellt. Das geht nur anders, wenn die zusätzliche
      // Parameterzahl vorher bekannt und immer gleich ist.
      call_variadic_function(foo, ints, 4);
      foo(4, 5, 6, 7, 8);
      return 0;
    }
    


  • mit va_list und co...

    void foo(bool arr, int count, ...) 
    { 
      va_list list; 
    
      va_start(list, count); 
      if (arr)
      {
    	int* array = (int*)va_arg(list, int); // auf dem stack steht die Adresse des arrays
    	for(int c = 0; c < count; c++) 
    		std::cout << array [c] << " "; 
      }
      else
      {
    	  for(int c = 0; c < count; c++) 
    		std::cout <<va_arg(list, int) << " "; 
      }
      va_end(list); 
      std::cout << std::endl; 
    
    } 
    
    int main() 
    { 
      int ints[] = {1, 2, 3, 4}; 
      foo(true, 4, ints); 
      foo(false, 4, 5, 6, 7, 8); 
      return 0; 
    }
    


  • @Tobias Gerg
    Er will die Varargs-Funktion aufrufen, nicht eine implementieren.
    Und zwar so, als ob die Parameter alle direkt übergeben werden, NICHT so als ob ein zu einem Zeiger zerfallenes Array übergeben wurde.

    Da wird ihm va_list etc. wenig nutzen. Behaupte ich mal so 🤡



  • hustbaer schrieb:

    @Tobias Gerg
    Er will die Varargs-Funktion aufrufen, nicht eine implementieren.
    Und zwar so, als ob die Parameter alle direkt übergeben werden, NICHT so als ob ein zu einem Zeiger zerfallenes Array übergeben wurde.

    Da wird ihm va_list etc. wenig nutzen. Behaupte ich mal so 🤡

    Mag sein, ich bezog mich auf den unten genannten Code...

    Evoli schrieb:

    nwp3 schrieb:

    void foo(int a, ...);
    int ia[] = {1, 2, 3, 4, 5};
    foo(2, ia);
    

    Ich verstehe dein Problem nicht.

    Bei mir funtioniert das nicht:

    #include <cstdarg>
    #include <iostream>
    using namespace std;
    
    void foo(int count, ...)
    {
      va_list list;
      va_start(list, count);
      for(int c = 0; c < count; c++)
        std::cout << va_arg(list, int) << " ";
      va_end(list);
     std:cout << std::endl;
    
    }
    
    int main()
    {
      int ints[] = {1, 2, 3, 4};
      foo(4, ints);
      foo(4, 5, 6, 7, 8);
      return 0;
    }
    
    $ g++ tmp.cpp && ./a.out 
    -1157254800 -1157254536 4 -1233998720
    5 6 7 8
    

    _____________________________________________________

    Ahhhh ... beim durchlesen habe ich wohl den

    Das Problem ist, dass die variadic function nicht von mir geschrieben, sondern Teil einer Bibliothek ist (wl_proxy_marshal in libwayland um genau zu sein). Daher kann ich diese nicht verändern.

    übersehen ...


Anmelden zum Antworten