2015-07-21 61 views
1

爲什麼會出現這樣的:靜態成員數組的定義本身使用sizeof操作符的

error: invalid application of 'sizeof' to incomplete type 'A' 

,當我嘗試這樣做:

class A 
{ 
    int m_i; 
    static char m_j[sizeof(A)]; 
}; 

我的假設下,這顯然是在這種情況下明確sizeof(A)將是sizeof(int)。但我的編譯器似乎並不這麼認爲。

+0

可以通過聲明m_j爲char *和分配在外部聲明的空間避開它。 – cup

+1

@LưuVĩnhPhúc您誤解了這個問題:'m_j'是靜態的,並且使其與班級的大小相同,這是非常有意義的。 – Quentin

回答

5

正如錯誤消息所示,sizeof只能對完整類型進行操作。在您調用它時,A尚未完成。

+0

這聽起來很合理...... 有什麼解決方法可以實現我綁定的目標嗎? – user2950911

+0

@ user2950911如果A的私有成員僅用於一個源文件,則可以將'm_j'數組聲明爲該源文件內的靜態全局對象。 – KABoissonneault

1

C++編譯器從上到下分析你的代碼。在你調用sizeof時,你的班級沒有完全定義,因此,這個大小還不能確定。舉例來說,如果其他成員宣言是什麼線以下:

class A 
{ 
    int m_i; 
    static char m_j[sizeof(A)]; // Uh oh, m_i2 is not known here, yet 
    int m_i2; 
}; 

由於這樣的問題,你可以使用sizeof後才類是完全定義的,即後的右大括號。

template <class = void> 
struct A { 
    int i; 

    static auto& m_j() { 
     static char arr[sizeof(A)]; 
     return arr; 
    } 
}; 

int main() 
{ 
    auto array = A<>::m_j(); 
} 

編譯器等待,直到使用m_j實例化功能,在這一點A已經完全宣稱:

0

,如果你使用模板這是可能的。

活生生的例子here

+0

爲什麼你需要一個模板?它工作的原因是因爲你將靜態數組放入成員函數中。 – juanchopanza

+1

@juanchopanza如果您不使用推導返回類型,則需要延遲實例化。我不確定這是否是標準行爲。 – Quentin