2013-02-22 53 views
1

我正在寻找答案,但是我找不到任何相关信息。让我们的例子:C++可变参数列表

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); 
} 

如何参数abc通过呢?按价值,或通过参考和如何使用va_arg请求他们?那么MyClass的构造函数/析构函数呢?在C++标准中,哪种行为是指定的?

+0

'va_arg'的示例:http://en.cppreference.com/w/cpp/utility/variadic/va_arg – 2013-02-22 14:50:19

+0

可变参数函数:http://en.cppreference.com/w/cpp/utility/variadic和来自C++ 11的可变参数模板:http://www.cplusplus.com/articles/EhvU7k9E/ – CCJ 2013-02-22 14:53:11

+0

您不能使用用户定义的构造函数传递对象。 – 2013-02-22 14:57:53

回答

5

绝不应该在var-arg函数中使用用户定义的类型。使用C++ 11可变参数模板。

如果你的类不荚型 - 它是由标准不确定,这要归功于沃恩卡托备注

n3337 5.2.2/7

传递类类型的潜在评估参数(第9条)具有不重要的复制构造函数,非平凡的移动构造函数或非平凡的析构函数,并且没有相应的参数,它是用实现定义的语义有条件地支持的。

否则,你可以并且它会是正确的,但是你没有。

+0

然后,只有在确实需要时才使用MyClass *才是安全的。我测试了这个msvc,它似乎是合法的。 – Raxvan 2013-02-22 15:11:32

+1

当然,他没有给我们足够的证据表明'MyClass'不是一个POD。尽管传统上,POD类是用'struct'关键字定义的,类似于'class MyClass {public:int a; int b; };'是完全合法的,并且是POD。 – 2013-02-22 15:13:15

3

按价值。但要小心,如果MyClass不是POD,则程序 具有未定义的行为(C++ 03,§5.2.2/ 7),或者MyClass具有 的非平凡复制构造函数,移动构造函数或析构函数, 的操作是有条件支持的,实现 定义了语义(C++ 11,§5.2.2/ 7)。

在你的榜样,传递a和传球c正是 相同的操作(除了c不能绑定到 非const引用,但在这里,这不是一个问题,因为 可变参数都是按值传递)。因此,当致电foo时,您的 通过0a的副本,指针b的副本以及a的副本 。为了在foo中访问它们,您需要声明 va_arg中的类型为int,MyClass,MyClass*MyClass