如何解决是否可以获取可变参数上的参数数量?
我一直在研究如何使用可变数量的参数声明函数或类成员,并且遇到了可变参数函数,但是我想知道是否有某种方法可以访问传递给函数的参数数量,,而不必像大多数文档所介绍的那样直接将其作为第一个参数传递。我也知道我可以使用可变参数模板或std::initializer_list
,但是由于我希望传递多个相同类型的参数 ,所以这些参数看起来太通用和/或复杂语法。
#include <cstdarg>
bool func(int args...) {
va_list list;
va_start(list,args);
int val = args;
while(val >=0) {
std::cout << val << std::endl;
val = va_arg(list,int);
}
return true;
}
bool other_func(int c,int args...) {
va_list list;
va_start(list,args);
int val = args;
for (int i = 0; i<c; i++) {
std::cout << val << std::endl;
val = va_arg(list,int);
}
return true;
}
int main(int argc,char const *argv[]) {
func(2,7,47,-1,23 /* ignored */);
other_func(3 /* n of parameters */,2,47);
return 0;
}
在这些特定示例中,func
循环遍历输入自变量,直到找到负值(以说明问题并强制停止标志),而other_func
要求将自变量数量设置为作为第一个参数传递。在我看来,这两种实现方式都存在缺陷和不安全之处,是否有更好的方法来解决此问题?
解决方法
因为我一直想传递相同类型的多个参数
这正是std::initialiser_list<int>
会给你的。
您似乎对可变参数功能有误。声明int args...
并不意味着“一定数量的int
参数”,而是意味着“一个名为args的int
,后跟任意数量的任何类型的参数”
如果您使用C样式的varargs,则否,您一次只能解析一个参数列表。
如果您选择使用c ++ 11,则可以改用可变参数模板函数,并使用sizeof ...运算符获取参数包的大小。
template<typename ... Args>
void func(char * leading,Args const & ... args)
{
/* sizeof...(Args) will give you the number of arguments */
}
,
如果您有C ++ 17,可以在编译时使用可变参数非类型模板参数和折叠表达式来完成:(Live Demo)
template<int... args>
constexpr bool func() {
return ((args < 0) || ...);
}
int main() {
static_assert(func<2,7,47,-1,23>());
static_assert(!func<1,2,3>());
return 0;
}
(如果您使用的是C ++ 20,则可以使用consteval
而不是constexpr
。Demo 2来执行编译时计算)
如果您坚持使用C ++ 11,那么仍然可以在编译时进行操作,但是我们将需要更多样板(Live Demo 3)
#include <type_traits>
namespace detail
{
template<bool...>
struct disjunction;
template<bool b>
struct disjunction<b> : std::integral_constant<bool,b>
{};
template<bool left,bool... Bs>
struct disjunction<left,Bs...> : std::conditional<left,disjunction<left>,disjunction<Bs...>>::type
{};
}
template<int... args>
constexpr bool func() {
static_assert(sizeof...(args) > 0,"Need to pass more than 1 integer");
return detail::disjunction<(args < 0)...>::value;
}
int main() {
static_assert(func<2,23>(),"There is one negative number");
static_assert(!func<1,3>(),"There aren't any negative numbers");
return 0;
}
,
否,没有标准的方法可以检测传递给(C风格)可变参数的参数的数量。您将必须在初始参数中传递数字,或使用某种可以被识别为序列结尾的终止符。为此,最好使用C ++工具。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。