我正在寻找答案,但我找不到任何相关信息。我们举个例子:
class MyClass
{
//member functions and variables
};
void foo(int pivot,...)
{
va_list arguments;
va_start(arguments,pivot);
//va_arg(arguments,???)
va_end(arguments);
}
void bar()
{
MyClass a;
MyClass * b = &a;
const MyClass & c = a;
foo(0,a,b,c);
}
参数a
,b
和c
如何通过?通过价值或参考以及如何使用va_arg来询问它们?那么MyClass的构造函数/析构函数呢? c ++标准中指定了哪种行为?
答案 0 :(得分:5)
你永远不应该在var-arg函数中使用用户定义的类型。使用C ++ 11可变参数模板。
如果您的课程不是pod类型 - 标准未指定,感谢Vaughn Cato的评论
n3337 5.2.2 / 7
传递具有非平凡性的类型(第9条)的可能被评估的参数 复制构造函数,一个非平凡的移动构造函数,或一个非平凡的析构函数,没有相应的 参数,由实现定义的语义有条件地支持。
否则,你可以而且它是正确的,但你不应该。
答案 1 :(得分:3)
按价值计算。但要注意,如果MyClass
不是POD,那么该程序
有未定义的行为(C ++ 03,§5.2.2/ 7),或MyClass
有
一个非平凡的拷贝构造函数,移动构造函数或析构函数,
通过实施有条件地支持该操作
定义的语义(C ++ 11,§5.2.2/ 7)。
在您的示例中,传递a
并传递c
正是如此
相同的操作(除了c
不能绑定
一个非const引用,但这不是问题,因为
varargs都是通过价值)。因此,在致电foo
时,您
传递0
,a
的副本,指针b
的副本和副本
a
。要在foo
中访问它们,您需要声明
va_arg
中的类型为int
,MyClass
,MyClass*
和
MyClass
。