C++ c++;具有变量且参数数目未知的函数

C++ c++;具有变量且参数数目未知的函数,c++,function,C++,Function,可能重复: 我可以不设置参数个数可变的函数的参数个数吗?例如:可以实现以下接口吗 int sum(...) { ... } sum(1, 2, 3, 4); // return 10 不,你不能 只是不要使用变量参数。它们以任何可以想象的方式吮吸,完全不值得任何人花费时间。不,你不能 只是不要使用变量参数。他们吸吮着每一种可能的方式,完全不值得任何人的时间。 < P>一个C++变量函数必须知道它传递了多少(和什么类型)的参数。例如,printf的格式字符串告诉它需要哪些额外的参数 你的总和

可能重复:

我可以不设置参数个数可变的函数的参数个数吗?例如:可以实现以下接口吗

int sum(...) { ... }

sum(1, 2, 3, 4); // return 10
不,你不能

只是不要使用变量参数。它们以任何可以想象的方式吮吸,完全不值得任何人花费时间。

不,你不能


只是不要使用变量参数。他们吸吮着每一种可能的方式,完全不值得任何人的时间。

< P>一个C++变量函数必须知道它传递了多少(和什么类型)的参数。例如,printf的格式字符串告诉它需要哪些额外的参数

你的
总和
无法知道它是4整数还是10整数。您可以将第一个参数设置为一个长度:

int sum(int howmany, ...) { ... }

所以函数知道后面有多少整数。但是,你应该只通过一个数组(或者如果你感觉C++),则C++的变量函数必须知道它传递了多少个(和什么类型的)参数。例如,printf的格式字符串告诉它需要哪些额外的参数

你的
总和
无法知道它是4整数还是10整数。您可以将第一个参数设置为一个长度:

int sum(int howmany, ...) { ... }

所以函数知道后面有多少整数。但实际上,您应该只传递一个数组(或者向量,如果您感觉C++'y)

有多种方法可以解决您的问题。我将介绍几个:

方法1: -创建一系列重载求和函数以满足您的需要

缺点 -代码膨胀

这可以通过使用标题创建多个函数来实现:

int sum(int a);
int sum(int a, int b);
int sum(int a, int b, int c);
等等

方法2: -使用链表创建自定义类,并传入指向链表头部的指针。假设您不知道要传递的数据量,这可能是您在这种情况下的最佳举措

函数标题:

int sum(LinkedList *headPointer);
int sum(int input[]);
int sum(int a=0, int b=0, int c=0, int d=0,... int n=0);
方法3: -传入一个变量数组

函数标题:

int sum(LinkedList *headPointer);
int sum(int input[]);
int sum(int a=0, int b=0, int c=0, int d=0,... int n=0);
方法4: -创建具有自动设置变量的函数

函数标题:

int sum(LinkedList *headPointer);
int sum(int input[]);
int sum(int a=0, int b=0, int c=0, int d=0,... int n=0);

有多种方法可以解决您的问题。我将介绍几个:

方法1: -创建一系列重载求和函数以满足您的需要

缺点 -代码膨胀

这可以通过使用标题创建多个函数来实现:

int sum(int a);
int sum(int a, int b);
int sum(int a, int b, int c);
等等

方法2: -使用链表创建自定义类,并传入指向链表头部的指针。假设您不知道要传递的数据量,这可能是您在这种情况下的最佳举措

函数标题:

int sum(LinkedList *headPointer);
int sum(int input[]);
int sum(int a=0, int b=0, int c=0, int d=0,... int n=0);
方法3: -传入一个变量数组

函数标题:

int sum(LinkedList *headPointer);
int sum(int input[]);
int sum(int a=0, int b=0, int c=0, int d=0,... int n=0);
方法4: -创建具有自动设置变量的函数

函数标题:

int sum(LinkedList *headPointer);
int sum(int input[]);
int sum(int a=0, int b=0, int c=0, int d=0,... int n=0);

您可能希望通过编写类似于
向量的函数来实现这一点,您将使用带括号的初始值设定项列表动态构造该向量:

int sum(std::vector<int> const &n) { 
    return std::accumulate(begin(n), end(n), 0);
}

警告:这个特性最近才添加到C++中,所以一些编译器(例如VC++)不支持它——尽管其他(例如,G+++ 4.7),do.

你可能想通过编写函数来获取类似于<代码>向量< />的函数,你将用一个支持的初始化列表来构建:

int sum(std::vector<int> const &n) { 
    return std::accumulate(begin(n), end(n), 0);
}

警告:这个特性最近才被添加到C++中,所以一些编译器(例如,VC++)不支持它——尽管其他(例如,G+++ 4.7),do.

传统是凌乱的,不是类型安全的,但是在你可以使用干净和使用(编译时)递归:

// Base case for recursion
template <typename T>
inline T sum(T n) {
  return n;
}

// Recursive case
template <typename T, typename... Args>
inline T sum(T n, Args... args) {
  return n + sum(args...);
}
但是,由于递归模板函数的返回类型仅取自第一个参数,如果在一次调用中混合使用不同的参数类型,则可以得到令人惊讶的结果:
sum(2.5,2)
按预期返回4.5,但是
sum(2,2.5)
返回2,因为返回类型是
int
,不
double
。如果您想更有趣,可以使用new指定返回类型是
n+sum(args…
的自然类型:

// Recursive case
template <typename T, typename... Args>
inline auto sum(T n, Args... args) -> decltype(n + sum(args...)) {
  return n + sum(args...);
}
//递归大小写
模板
内联自动求和(tn,Args…Args)->decltype(n+sum(Args…){
返回n+和(参数…);
}
现在
sum(2.5,2)
sum(2,2.5)
都返回4.5

如果您的实际逻辑比求和更复杂,并且您不希望将其内联,则可以使用内联模板函数将所有值放入某种容器(例如
std::vector
std::array
)并将其传递到非内联函数中,以在最后完成真正的工作。

传统的方法比较混乱,而且类型不安全,但在中,您可以使用and(编译时)递归干净地完成这项工作:

// Base case for recursion
template <typename T>
inline T sum(T n) {
  return n;
}

// Recursive case
template <typename T, typename... Args>
inline T sum(T n, Args... args) {
  return n + sum(args...);
}
但是,由于递归模板函数的返回类型仅取自第一个参数,如果在一次调用中混合使用不同的参数类型,则可以得到令人惊讶的结果:
sum(2.5,2)
按预期返回4.5,但是
sum(2,2.5)
返回2,因为返回类型是
int
,不
double
。如果您想更有趣,可以使用new指定返回类型是
n+sum(args…
的自然类型:

// Recursive case
template <typename T, typename... Args>
inline auto sum(T n, Args... args) -> decltype(n + sum(args...)) {
  return n + sum(args...);
}
//递归大小写
模板
内联自动求和(tn,Args…Args)->decltype(n+sum(Args…){
返回n+和(参数…);
}
现在
sum(2.5,2)
sum(2,2.5)
都返回4.5


如果您的实际逻辑比求和更复杂,并且您不希望将其内联,则可以使用内联模板函数将所有值放入某种容器(例如
std::vector
std::array
)并将其传递到非内联函数中,以完成最后的实际工作。

如果您的编译器支持的话,设置一个可变模板来完成这项工作应该不难。我会发布一个答案,但我手头没有这样一个编译器来测试我的代码。假设你的编译器支持,设置一个可变模板来实现这一点应该不难。我会发一封电子邮件