如何将n个参数传递给n未知的函数

时间:2014-10-09 22:37:35

标签: c++ function variadic-functions

我需要将n个参数传递给函数。用户可以根据需要输入任意数量的参数,但我们不知道他将传递的参数数量。但我用va_list看到的所有实现都包含一个计数,但在这里我们不知道数字。它看起来像

        void xyz(int x[],...);

我们只有数组

使用的功能就像。

        xyz({1,2,3},{1,1},{2},{3,3,3})

然后我希望我的函数中的3个数组在可能的情况下使用单独的变量。我需要在这些数组中进行一些计算。这可能在c ++ ??

3 个答案:

答案 0 :(得分:1)

您可以使用可变参数函数(如printf),但通常不愿意使用。

您可以将initializer_list作为参数。这将允许您获取可以全部转换为单一类型的项目的支撑列表:

void f(std::initializer_list<int> l);

...你可以称之为:

f({1, 2, 3, 4});

还有一个std::vector的ctor需要std::initializer_list,所以你可以拿一个(引用)vector<T>并完成大致相同的操作。但是请注意(与C ++的大多数部分不同),这不支持缩小转换次数,因此对于需要f的上述int,如果您尝试传递,则可能会出错(对于例如)double代替。

如果您不喜欢大括号,或者想要支持不同类型的参数,则可以使用可变参数模板。例如,这是我前一段时间发布的函数,它采用任意数量的(几乎)任意类型的参数,将它们放在一个字符串中,并将结果字符串写入套接字:

#include <sstream>
#include <string>
#include <iostream>

template <class T>
std::string stringify(T const &t) { 
    std::stringstream b;
    b << t;
    return b.str();
}

template<typename T, typename... Args>
std::string stringify(T arg, const Args&... args) {
    return stringify(arg) + stringify(args...);
}

template<typename... Args>
void send_cmd(const Args&... args) { 
    std::string buffer = stringify(args...);
    send(sock, buffer.c_str(), buffer.length(), 0);
}

int main() {
    std::string three{" three"};

    send_cmd("one: ", 1, " two: ", 2, three, "\n");

    return 0;
}

答案 1 :(得分:0)

#include <iostream>
#include <initializer_list>
#include <list>
#include <vector>
#include <algorithm>
#include <iterator>

// Base case: do nothing once all inputs have been processed
void implementation(const std::list<int>& acc) {}

// Recursively pick off one sequence at a time, copying the data into
// the accumulator
template<class ONE, class ... REST>
void implementation(std::list<int>& accumulator,
                    const ONE& first,
                    const REST& ... rest) {
  std::copy(begin(first), end(first), std::back_inserter(accumulator));
  implementation(accumulator, rest...);
}

// Interface, hiding the creation of the accumulator being fed to the
// template-recursive implementation.
template<class ... REST>
std::vector<int> concatenate(const std::initializer_list<REST>& ... rest) {
  std::list<int> accumulator;
  implementation(accumulator, rest...);
  return std::vector<int>(begin(accumulator), end(accumulator));
}

template<class SEQ>
void show_contents(const SEQ& s) {
  std::copy(begin(s), end(s), std::ostream_iterator<int>(std::cout, " "));
  std::cout << std::endl;
}

int main() {

  show_contents(concatenate({1,2}, {3,4,5}, {6,7}));
  show_contents(concatenate({8,9}));
  show_contents(concatenate({9,8,7}, {6,5}, {4,3}, {2,1}));

}

答案 2 :(得分:0)

如果所有参数的类型相同,则可以传递std::vector

void xyz(std::vector<int>& parameters)
{
  //...
}

在您的示例中,看起来每个参数可能具有不同数量的数字 这可以使用std::vector< std::vector< int> >

来处理
void abc(std::vector< std::vector< int> >& parameters)
{
  // Each slot of the outer vector is denoted by your {...} syntax.
  std::vector<int>& parameter2 = parameters[1];

  // Each number within {...} is represented by a vector of integers
  std::cout << "{"
            << parameter2[0] << ", "
            << parameter2[1] << ", "
            << parameter2[2]
            << "}\n";
}

编辑1:传递参数

您可以将数字放入变量并将变量传递给函数:

int main(void)
{
  // Load up the individual parameters.
  std::vector<int> p1 = {1};
  std::vector<int> p2 = {2, 3};
  std::vector<int> p3 = {5, 6, 7};

  // Place all parameters into one container
  std::vector< std::vector< int > > parameters = {p1, p2, p3};

  // Call the function with the parameters
  abc(parameters);

  return 0;
}