我们如何更改此函数以支持多个参数
How do we change this function to support multiple arguments?
#include <iostream>
using namespace std;
class SampleClass
{
public:
int test(int ... arguments)
{
cout << arguments[0] << endl; // Access first element in array
return sizeof(arguments);
}
};
int main()
{
SampleClass lol;
cout << lol.test(3, 1, 4, 2, 5, 0) << endl;
return 0;
}
由于我对C++语义的理解有限,test
函数失败。但是我该如何修复它,以便它可以访问参数 lits 中的第一个元素,然后返回 arguments
的大小?
正如@Nik指出的那样,我显然可以在数组中传递,但这并没有真正的乐趣!我尝试这样做只是为了学习 - 看看这在C++中是否可行。
既然我们都在猜测你想要什么,我就抛出:
template <typename ... Ts>
size_t test(Ts ... arguments) {
auto unused = { 0, ((cout << '[' << arguments << "]n"), 0)...};
(void)unused;
return sizeof...(arguments);
}
它适用于不同类型的参数(住在科利鲁(。不过,这个解决方案有点太"聪明"了,无法阅读。
这里的诀窍是构建一个大括号初始化列表 - {...}
的东西 - 其元素通过按顺序处理可变参数来初始化。然后,您说服编译器所述初始值设定项列表不用于任何内容,因此代码将进行优化以仅生成所需的副作用。
C++ 中的逗号运算符计算最右侧子表达式的值。计算其他子表达式并丢弃其值。因此,((cout << '[' << arguments << "]n"), 0)
具有将一些东西转储到cout
(包括可变参数之一(并计算为 0 的效果。使用...
扩展包后,该行代码实际上是:
auto unused = { 0, ((cout << '[' << arg0 << "]n"), 0),
((cout << '[' << arg1 << "]n"), 0),
((cout << '[' << arg2 << "]n"), 0) };
cout
垃圾被评估其副作用并丢弃,整个东西被推断为std::initializer_list<int>
就像我们写的那样
auto unused = { 0, 0, 0, 0 };
(开头有额外的零,以避免有人在没有参数的情况下调用函数时出现语法错误。
(void)unused;
线正在铸造unused
void
。它将编译为绝对没有,但通常也会告诉编译器不要警告我们unused
是一个未使用的变量。
尝试这样的事情
double test( int num, ... )
{
va_list arguments; // A place to store the list of arguments
double sum = 0;
va_start ( arguments, num ); // Initializing arguments to store all values after num
for ( int x = 0; x < num; x++ ) // Loop until all numbers are added
sum += va_arg ( arguments, double ); // Adds the next value in argument list to sum.
va_end ( arguments ); // Cleans up the list
return sum / num; // Returns the average
}
所以你的点在你的参数列表的错误一侧。我希望这有所帮助,祝你好运。
嗯。您正在尝试混合C++的两个功能,variadic-templates
和variable-length argument list
。您的代码根本无法编译,因为您在这里没有模板,并且声明应该是variable-length argument list
int test(int arguments...)
您可以使用标头中的函数访问此列表中的值cstdarg
。
有了variadic-templates
你可以做以下事情
class Derived
{
public:
template<int... arguments>
int test()
{
int array[] = {arguments...};
return sizeof(array) / sizeof(*array);
}
};
像这样使用它
cout << lol.test<3, 1, 4, 2, 5, 0>() << endl;
我不太确定我是否完全理解你的问题。如果您想访问函数而不是模板的"第一个"参数,我认为这样的事情会为您完成,但我可能完全误解了您在这里的目的:
#include <iostream>
template<typename... Args>
int foo(int arg0, Args... args);
template<>
int foo(int arg0)
{
// here just to catch expansion
std::cout << '[' << arg0 << ']' << std::endl;
return 1;
}
template<typename... Args>
int foo(int arg0, Args... args)
{
foo(arg0);
foo(args...);
return 1 + sizeof...(args);
}
int main()
{
std::cout << foo(1,2,3,4,5) << std::endl;
std::cout << foo(100,200,300) << std::endl;
int a=10, b=20;
std::cout << foo(a,b) << std::endl;
return 0;
}
输出
[1]
[2]
[3]
[4]
[5]
5
[100]
[200]
[300]
3
[10]
[20]
2
您有多种选择。
1(使用椭圆(只有无限的arg列表(:
int foo(int a1, ...);
您的代码需要像 printf 一样解析椭圆。 您将被限制为内置 C 类型。
2( 使用多个模板:
template<typename T1> int foo(T1 a1);
template<typename T1, typename T2> int foo(T1 a1, T2 a2);
// more templates for more arguments
This method us used, usually up to 10 parameters (10 template functions)
3( 使用具有默认值或非法值的函数,这样您就会知道哪个是最后一个有效参数:
int foo(int a1, int a2 = -1, int a3 = -1, int aN = -1);
- OpenCL 是否支持向量作为内核参数?
- 如何根据基类型支持不同数量的参数?
- C++中的可变参数函子可以支持命名字段吗?
- 为什么libc++不支持在多集上推导类模板参数?
- 如果创建支持返回可变参数类型列表的通用模板 API,我应该使用 std::tuple 还是其他东西?
- 支持与参数有关的查找的编译器
- 有没有办法在我的通用功能路由器设计中支持"常量引用"作为功能签名参数?
- 为了支持移动语义,应通过unique_ptr,值或rvalue获取功能参数
- C 支持名称参数
- apache-frift是否支持函数变量作为参数
- 如何使用 C++11 可变参数模板来定义由向量元组支持的元组向量
- 为什么说C++不支持参数多态性
- OpenCV错误:cvGetMat中有错误的标志(参数或结构字段)(无法识别或不支持的数组类型)
- 我们如何更改此函数以支持多个参数
- 如何在不支持可变参数模板参数时为元组专用化类模板
- 命令行程序如何支持管道参数
- 如何更改 MSVC++ 的 std::tuple 支持的模板参数数量?
- 如何避免LLVM的支持命令行泄漏库参数?
- C++参数支持字符串和整数的结构
- 模板/预处理器的hack可以用来支持参数列表中间的变量参数吗?