2010-08-31 85 views
3

我看到別人的C++代碼有函數聲明如下圖所示:「......」 在函數原型

void information_log(const char* fmt , ...) 

或catch塊像

catch(...) 
{ 
} 

是什麼 「......」 是什麼意思?

回答

8

省略號...,在一個函數原型,被用於表示該功能的可變參數,即,它使要傳遞到該函數的自變量的變量數。在這種形式中,一個功能必須定義一些方式用戶可以精確地指定它們提供了多少個參數,因爲C++中的可變參數庫函數不能動態確定這些信息。

例如,標準輸入輸出功能printf是一種這樣的功能與原型:

int printf(const char *format, ...); 

據推測,從兩個原型之間的相似性,則描述被設計的information_log功能鏡像多的printf的功能,甚至可能在內部使用printf,或其堂兄弟。

以下是如何實現一個可變參數函數的示例:

// cstdarg provides access to the arguments passed to the ellipsis 
#include <cstdarg> // or (#include <stdarg.h>) 
#include <cstdio> 
#include <cstring> 

// Concatenates as many strings as are present 
void concatenate(char ** out, int num_str, ...) 
{ 
    // Store where the arguments are in memory 
    va_list args; 

    // Find the first variadic argument, relative to the last named argument 
    va_start(args, num_str); 

    int out_len = 0; 
    int * lengths = new int[num_str]; 
    char ** strings = new char*[num_str]; 

    // Extract the strings from the variadic argument list 
    for(int i = 0; i < num_str; i++) 
    { 
     // Specify the position in the argument list and the type 
     // Note: You must know the type, stdarg can't detect it for you 
     strings[i] = va_arg(args, char *); 
     lengths[i] = strlen(strings[i]); 
     out_len += lengths[i]; 
    } 

    // Concatenate the strings 
    int dest_cursor = 0; 
    (*out) = new char[out_len + 1]; 
    for(int i = 0; i < num_str; i++) 
    { 
     strncpy((*out) + dest_cursor, strings[i], lengths[i]); 
     dest_cursor += lengths[i]; 
    } 
    (*out)[dest_cursor] = '\0'; 

    // Clean up 
    delete [] strings; 
    delete [] lengths; 
    va_end(args); 
} 

int main() 
{ 
    char * output = NULL; 

    // Call our function and print the result 
    concatenate(&output, 5, "The ", "quick", " brown ", "fox ", "jumps!\n"); 
    printf("%s", output); 

    delete [] output; 
    return 0; 
} 
+1

實例。 (+1) – 2010-08-31 04:00:47

+0

printf如何動態確定提供的參數的數量呢? – f0ster 2011-04-26 03:09:31

+0

@ f0ster在第一個c-string參數'printf'中指定參數個數。該函數將解析格式化字符串,並且每次找到以%開頭的令牌時,它將把它視爲特殊的(即從可變參數列表中讀取下一個參數)。在我的代碼示例中,您會看到我對'printf(「%s」,output)的調用;'','%s'指示函數期望一個字符串參數。參數從左到右依次對應格式化字符串中的標記。希望這可以解決這個問題。 – TheDrakeMan 2011-11-15 09:57:47

1

請參閱Functions with an Unspecified Number of Parameters

使用省略號,...,用C++ 函數原型,指 功能可以用 指定未知數量和參數類型。 此功能可用於抑制 參數類型檢查並允許 函數的接口具有靈活性。 C++允許函數爲 ,聲明的參數數量不限,爲 。

3

對於一個捕獲,它意味着抓住任何東西。所以拋出的所有異常都會進入這個catch塊。

對於參數列表,它意味着可變數量的參數將在那裏。你必須使用stdarg.h API來解析它們。

7

這裏真的是兩個單獨的問題,只是使用相同的符號。 :-)

原型只是表示可變數量的參數。我真的可以說的是,它有點像C的printf函數,如果你碰巧知道這一點。這個函數只是在需要它們的時候繼續提供參數。

catch (...)代碼僅僅意味着,發現任何異常。 (通常你把這個一些特定catch塊後,使這一工作作爲一個「包羅萬象」。)

3

$ 5.2.2/6 - 「一個函數可以聲明 接受更少的參數(通過 聲明默認參數(8.3.6)) 或多個參數(通過使用 省略號,... 8.3.5),比在功能 定義參數的數量 (8.4)[注:這意味着 除了使用省略號(...) 以外,參數可用於每個參數的 。]「

,在OP

很好總結了 「information_log」 的申報interepretation $ 15.3/6 - 「A ......在處理程序的 異常聲明功能 類似...在功能 參數聲明;它指定一個 匹配任何異常。如果存在,一個 ...處理程序應是最後的處理程序 其try塊。」

雖然不是一個標準術語,它經常被稱爲包羅萬象的條款或者捕獲所有的處理程序。

void f(){ 
    try{ 
     throw 2.2;  // throw double 
    } 
    catch(int){}    // standard conversion from double to int not permitted 
    catch(...){ 
     cout << "catch it here"; // is caught here in catch all clause 
    } 
} 

int main(){ 
    f(); 
}