#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中的FIRST元素然后返回arguments
的大小?
答案 0 :(得分:3)
尝试这样的事情
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
}
所以你的参数列表中的点是错误的。 我希望这有助于和好运。
答案 1 :(得分:3)
嗯。您正在尝试混合使用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;
答案 2 :(得分:3)
既然我们都在猜你想要什么,我会投入:
template <typename ... Ts>
size_t test(Ts ... arguments) {
auto unused = { 0, ((cout << '[' << arguments << "]\n"), 0)...};
(void)unused;
return sizeof...(arguments);
}
适用于不同类型的参数(Live at Coliru)。但是,这个解决方案有点过于“聪明”,无法读取。
这里的技巧是构建一个braced-initializer-list - {...}
东西 - 通过按顺序处理可变参数来初始化其元素。然后你说服编译器说所谓的初始化列表没有用于任何东西,所以代码将被优化以产生所需的副作用。
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 };
(如果有人用 no 参数调用该函数,那么开头就会出现额外的零以避免语法错误。)
(void)unused;
行将unused
投射到void
。它将编译为绝对没有,但通常也会告诉编译器不要警告我们unused
是一个未使用的变量。
答案 3 :(得分:2)
我不太确定我完全理解你的问题。如果你想访问&#34;第一个&#34;函数的参数而不是模板,我认为这样的东西会为你做,但我可能完全误解了你的目的:
#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
答案 4 :(得分:1)
您有几种选择。
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);