2011-04-26 51 views
5

我已經搜索了一個答案的stackoverflow,但是我無法得到相關的東西。在C++中使用標記進行靜態結構初始化

我試圖通過指定的標籤來初始化初始值的靜態結構實例,但我會在編譯時錯誤:

src/version.cpp:10: error: expected primary-expression before ‘.’ token

下面的代碼:

// h 
typedef struct 
{ 
    int lots_of_ints; 
    /* ... lots of other members */ 
    const char *build_date; 
    const char *build_version; 
} infos; 

錯誤代碼:

// C 

static const char *version_date = VERSION_DATE; 
static const char *version_rev = VERSION_REVISION; 

static const infos s_infos = 
{ 
    .build_date = version_date, // why is this wrong? it works in C! 
    .build_version = version_rev 
}; 

const infos *get_info() 
{ 
    return &s_infos; 
} 

因此,基本思想是繞過「其他成員」初始化,並只設置相關的build_datebuild_version值。 這用於C工作,但我不明白爲什麼它不會在C++中工作。

任何想法?

編輯

我意識到這代碼看起來簡單的C,它實際上是。整個項目是在C++中,所以我必須使用C++文件擴展名來防止生成文件依賴性混亂(%.o: %.cpp

+2

*爲什麼這是錯的?它適用於C!*主要是因爲C和C++是*不同的*語言。 – 2011-04-26 13:02:52

+1

@David - 但有足夠的共同點,並且有一個來源於另一個,並且持續分享想法,因此強調混淆是不公平的。 C99的某些部分已經被導入到C++ 0x中,比如「long long」。 – Steve314 2011-04-26 13:14:14

+0

@ Steve314:不要誤解我的意思,我沒有在困惑中強調(我沒有被強調),但是在這個問題上沒有混淆:他知道他們是不同的語言!當人們說因爲一個特性在C++中有效*它能夠在C++中工作時,我覺得它很有趣。考慮這一點,或'void f(int x){int array [x]; 「他們是不同的語言,儘管他們有共同的過去,但他們並不總是分享未來。 – 2011-04-26 18:38:54

回答

6

您使用的功能是C99功能,並且您使用的是不支持它的C++編譯器。請記住,雖然C代碼通常是有效的C++代碼,但C99代碼並非總是如此。

+1

爲了解釋更多 - 雖然C++最初有一個與C向後兼容的目標,但從長遠來看,保持「橫向」兼容性並不一定有意義。用C編寫但用C++調用的代碼對於兩者都是一種痛苦 - 接口不適合C++約定,但它在C編譯器上施加了約束和開銷(例如,通過C函數傳播的異常),這使得一些C球員將他們的耳朵吹出來。 – Steve314 2011-04-26 13:21:05

4

我相信這是作爲C99中的一個功能添加的,但從未成爲C++中的標準功能。

但是,有些編譯器可能會提供它作爲非標準的語言擴展。

4

下面的示例代碼定義了什麼,我認爲更C++的方式(不需要的typedef)一個結構,並使用一個構造函數來解決問題:

#include <iostream> 

#define VERSION_DATE "TODAY" 
#define VERSION_REVISION "0.0.1a" 

struct infos { 
    int lots_of_ints; 
    /* ... lots of other members */ 
    const char *build_date; 
    const char *build_version; 

    infos() : 
     build_date(VERSION_DATE), 
     build_version(VERSION_REVISION) 
    {} 
}; 

static const infos s_infos; 

const infos *get_info() 
{ 
    return &s_infos; 
} 

int main() { 

    std::cout << get_info()->build_date << std::endl; 
    std::cout << get_info()->build_version << std::endl; 

    return 0; 
} 
+0

這種初始化方式有一個C99版本中不存在的運行時間開銷,至少在原則上是這樣,儘管它通常不會造成大的開銷,如果某些編譯器可以優化開銷,我不會感到驚訝在某些情況下初始化,有效地給出與C99語法相同的結果。在這種情況下,它不需要比函數內聯和常量表達式的編譯時評估更多的處理。 – Steve314 2011-04-26 17:45:32

+0

@Steve - 真實,但它具有有效的C++優勢,所以在我的書中是一個加號(加號)! :) – 2011-04-26 18:20:08

+0

儘管我喜歡這樣,運行時開銷並不是我想要的。我會堅持老式的「全面的」靜態定義。不管怎麼說,還是要謝謝你 :) – Gui13 2011-04-27 08:30:50