2013-02-22 114 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