好吧,我很确定以前已经以某种方式讨论过这个问题,但我发现它显然太愚蠢了。
首先:我不是在寻找va_list和其他宏。 我正在寻找的是主要功能参数。
默认原型,正如你们所知道的那样:
int main(int argc, char *argv[]);
现在,我想要一些与我的程序类似的东西,但不知道究竟是怎么回事。
我们假设我们有这个功能:
void Function(int argc, unsigned short *args[]) {
for(int i = 0; i < argc; ++i) printf("%hu ", args[i]);
}
我想要这样的函数调用:
Function(5, 1, 2, 3, 4, 5);
那会有用吗? 因为我不想要va_list的“混乱”,也不想创建:
void AnotherFunction() {
unsigned short Args[] = { 1, 2, 3, 4, 5 };
Function(5, Args);
}
仅仅因为在这种情况下我只需要一个简单的指针。 有人可以指点我正确的方向吗?非常感谢你。
编辑: 感谢大家的宝贵意见。我会满足于'现在不能使用标准的C / C ++,并寻找一种不同的解决方法。
再次,非常感谢你。
答案 0 :(得分:3)
由于您还在C中使用C:标记,因此您可以将宏与所谓的复合文字结合使用
#define FUNCTION(ARGC, ...) (Function((ARGC), (unsigned short[]){ __VA_ARGS__ }))
这类型更安全,因为它将列表中的所有表达式转换为va_list
。
现代C ++现在还具有宏预处理阶段的unsigned short
功能。但我不知道你如何创建一个矢量作为临时值,用值初始化。
答案 1 :(得分:3)
g ++特定解决方案:
const size_t MAX_ARGS = 42;
void Function(int argc, const unsigned short (&args)[MAX_ARGS])
{
}
int main()
{
Function(5, {1,2,3,4,5});
}
如果您实际上不需要argc
参数,则可以编写模板:
template<size_t N>
void Function(const unsigned short(&args)[N])
{
// use N
}
这适用于C ++ 03。数组需要是const,否则你不能传递这样的临时初始化列表。如果您需要修改函数内的元素,则需要复制。
答案 2 :(得分:2)
使用默认参数。
Function(int argc, unsigned short *args[], int a = 2, int b = 3, int c = 4) ;
或您想要的任何类型。默认值以及此示例中的最后三个不需要传递给函数。你可以这样调用这个函数..
Function (argc, args, 5, 4, 3) ; //have to remember the maximum no. of parameters
我不知道你为什么要在你的程序中做这种事情。如果您不需要额外的变量,为什么要将它们包含在您的程序中? 但是
答案 3 :(得分:1)
要在C中编写类似的函数,您需要va_list和其他宏。这源于从C到装配的转换。在汇编中,您可以“查找”堆栈帧以查看传递给函数的更多参数。
但是,在C中,必须使用va_list类型和宏来完成此操作,因为在维护函数原型(参数的数量和类型)的同时,您可以使用其他内置机制。
请参阅http://www.gnu.org/software/libc/manual/html_node/Variadic-Functions.html。
答案 4 :(得分:1)
这是两个标准的C ++解决方案。两者都需要支持C ++ 11的编译器:
#include <iostream>
#include <algorithm>
#include <vector>
#include <iterator>
#include <utility>
template <typename T, typename... Us>
struct first_of_helper {
typedef T type;
};
template <typename... Ts>
using FirstOf = typename first_of_helper<Ts...>::type;
template <typename... Ts>
void f(Ts&&... args) {
typedef FirstOf<Ts...> T;
std::vector<T> v_args{std::forward<Ts>(args)...};
std::copy(v_args.begin(), v_args.end(), std::ostream_iterator<T>(std::cout, " "));
std::cout << "\n";
}
template <typename T>
void g(std::initializer_list<T> args) {
std::copy(args.begin(), args.end(), std::ostream_iterator<T>(std::cout, " "));
std::cout << "\n";
}
int main() {
f(1, 2, 3, 4);
g({1, 2, 3, 4});
}
在C ++ 11之前,唯一可移植的解决方案是通过va_args
。考虑一下:如果因为你可以编写更简单的代码而不需要va_args
,为什么它会首先存在?
答案 5 :(得分:0)
在C ++中基本上有两种方法可以做变量参数:
从C继承的varargs语法,它使用va_list等。
创建容器以传入参数。此容器可以是数组,std :: vector,std :: list等。
通过直接传递参数并允许编译器构造容器,您提出的解决方案是非常Java的。这就是Sun / Oracle决定在Java 5中实现var-args的方式,并且已经证明是一个非常方便的功能。不幸的是,C ++不支持这种语法。