在不传递参数数量且只有3个点的情况下,如何使用变差函数
How would it be possible to use variadic function without passing number of arguments and only with 3 dots?
考虑到下面的代码,是否可以在不获取参数数量的情况下定义一个可变函数?
void printFunction(...)
{
int noOfArgs = "Any way to get number of arguments?";
va_list args;
va_start(args, noOfArgs);
cout << va_arg(args, int) << endl;
for (int i = 2; i <= noOfArgs; i++)
{
cout << va_arg(args, int) << endl;
}
va_end(args);
}
int main()
{
printFunction(1, 2, 3, 4, 5);
return 0;
}
在Cva_args
中无法获取参数的数量。你能做的最好的事情就是使用一个结束序列的神奇值和一个宏来向用户隐藏它:
#define printFunction(...) actualPrintFunction(__VA_ARGS__, 42)
void actualPrintFunction(int first, ...)
{
va_list args;
va_start(args, first);
int arg;
std::cout << first << endl;
while((arg = va_arg(args, int)) != 42)
{
cout << arg << endl;
}
va_end(args);
}
正如评论中提到的,您也可以使用C++折叠表达式。上面的优点是与C兼容,编译速度更快,而C++方法为您提供了类型安全。
在C++11及以后的版本中,这很容易:
template<typename... Arguments>
void printFunction(Arguments &&...args) {
auto noOfArgs = sizeof...(Arguments);
然而,您使用的是一种老风格,即普通C,预处理器宏风格,这是非常不同的。首先,要使用预处理器宏,您需要至少有一个命名参数,该参数将用于启动va_list
,这是复杂性的开始。
我认为没有标准的方法来计算参数的数量,它可以通过多种方式实现,如果这是你真正想要的,我会将其标记为C
而不是C++
。
如何进入争论:有两种选择,让我们称之为"机关枪"answers"滴滴答答"——这是我的名字——:
#include <utility>
template<typename... Ts>
void ignoreResults(Ts &&...) {}
template<typename Argument>
int machineGunBullet(Argument &&arg);
inline void drip() {} // do nothing
template<typename A1, typename... Tail>
void drip(A1 &&a1, Tail &&...tail) {
// do something here with a1
drip(std::forward<Tail>(tail)...);
}
template<typename... Arguments>
void printFunction(Arguments &&...args) {
ignoreResults(machineGunBullet(std::forward<Arguments>(args))...);
// or
drip(std::forward<Arguments>(args)...);
}
这建立在编译器资源管理器中,https://godbolt.org/z/aSx2wv
从技术上讲,有一种方法类似于获取以null结尾的字符串的长度:使用特定的参数值来指定参数列表的末尾。
但是,请注意,为了使用va_start
,必须至少有一个命名参数。在您的示例中,您试图将一个局部变量传递到va_start
中,这是不允许的。该宏不接受"参数的数量"。它采用"可变参数开始之前的最后一个命名参数"。
也就是说:我建议不要使用C风格的变分函数。
相关文章:
- 如何在没有死锁和/或争用的情况下正确使用 std::mutex C++?
- 在这种情况下,使用 string_view 是否会导致不必要的字符串复制?
- 我们可以在不使用head指针的情况下通过使用head的简单变量而不是head的指针来实现链表吗
- 如何在不中断的情况下正确使用C++中的切换用例语句中的Fallthrough
- 在什么情况下,使用'const T*'输入参数比'const T&'更可取?
- 在这种情况下可以使用插入方法吗?
- 在这种情况下如何使用模板
- 在没有参数列表的情况下无效使用模板名称"节点"
- 在此特定情况下,使用unique_ptr的char数组
- Visual Studio:变量在未初始化的情况下被使用
- 为什么友元运算符<<在某些情况下使用,而在其他情况下不使用
- 错误:在没有参数列表的情况下无效使用模板名称“ExTree” ||如果解决这个问题怎么办?(初学者)
- 在同一系统上有多个GCC的情况下,使用哪个版本的libstdc++.so
- 在这种情况下,"使用"在做什么,正在存储什么?
- 套接字:在没有memcpy的情况下,使用recvfrom将UDP数据获取到字对齐的缓冲区
- 在存在分配器重新启动的情况下,使用null_mutex Safe是boost :: fast_pool_allocato
- 在这种情况下应该使用自动类型
- 在什么情况下应该使用C++临时代码
- 运行时检查失败 #3 - 变量"result"在未初始化的情况下被使用
- 如何在没有宏的情况下正确使用NED Trie