2014-10-09 64 views
0

我需要将n个参数传递给函数。用户可以输入尽可能多的参数,但我们不知道他将通过的参数数量。但是我所看到的所有使用va_list的实现都包含一个计数,但在这里我们不知道数字。它看起来像如何将n个参数传递给函数,其中n未知

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

,我们只有

该函数用于数组类似。

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

然后我想在我的函数中的3个数组在单独的变量,如果可能的话。我需要在这些数组中进行一些计算。这是可能的C++?

+2

如何将参数收集到一个字符串的矢量然后传递给函数? – billz 2014-10-09 22:38:30

+0

我需要坚持函数声明。但是我不能找到任何文档或任何其他地方做过类似的实现 – user2038791 2014-10-09 22:41:34

+0

什么是实际函数声明?它真的是无效的xyz(int x [],...)'? – 0x499602D2 2014-10-09 22:45:48

回答

1

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

您可以将initializer_list作为参数。这将让你把项目的支撑列表都可以转换为一个单一类型:

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

...你可以调用类似:

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

还有用于std::vector一个构造函数这需要std::initializer_list,所以你可以参考一个vector<T>并完成大致相同。但是请注意,与C++的大多数部分不同,这不支持缩小转换,因此对于上面需要int s的f,如果您尝试传递(例如)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; 
} 
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})); 

} 
+0

所以递归函数是一个好方法,但我想同时在阵列上工作。就像按顺序将所有数组合并到一个数组中。 – user2038791 2014-10-10 03:07:00

0

如果所有的参数都是同一类型的,你可以通过一个std::vector

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

在您的例子,它看起来像每个参数可以有不同数量的数字。

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:
这可以通过使用一个std::vector< std::vector< int> >处理传递参数

您可以将号码为变量,变量传递给函数:

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; 
} 
+0

那么我将如何能够传递参数?我可不可以 abc({1},{2,3},{5,6,7}); – user2038791 2014-10-10 01:20:06

+0

您可以在调用函数之前将数字放入数据结构或向量中吗? – 2014-10-10 13:44:04

+0

请参阅我的编辑1,了解加载参数和调用函数的示例。 – 2014-10-10 13:50:28

相关问题