2010-05-23 65 views
4

我已經在3個不同的編譯器(G ++,clang ++,CL.exe)中嘗試了下面的代碼片段,它們都向我報告它們不能消除重載的構造函數。現在,我知道如何修改對構造函數的調用,使其選擇一個或另一個(要麼明確表示第二個參數是無符號的文字值或明確地將其轉換)。C++在構造函數重載中的範圍和含糊不清

但是,我很好奇爲什麼編譯器會首先嚐試在構造函數中進行選擇,因爲其中一個構造函數是私有的,而對構造函數的調用發生在主函數中,該函數應該在類之外範圍。

任何人都可以啓發我嗎?

class Test 
{ 
private: 
     Test(unsigned int a, unsigned int *b) { } 
public: 
     Test(unsigned int a, unsigned int b) { } 
}; 

int main() 
{ 
     Test t1 = Test(1,0); // compiler is confused 
} 

回答

6

在C++中,對類成員的可訪問性不會影響其他語言的語義。相反,任何無效的訪問都會導致程序不合格。

換句話說,有輔助功能知名度。該標準有直接

應該指出,它是訪問受控制的成員和基類,而不是它們的可見性。當這些成員和基類不可訪問時,成員的名稱仍然可見,並且仍然會考慮隱式轉換爲基類。給定結構的解釋不考慮訪問控制。如果所建立的解釋使用不可訪問的成員名稱或基類,則該構造是不合格的。

+0

從標準文本+1 ... – 2010-05-23 16:39:43

+0

哇。謝謝。我昨天晚上閱讀了這部分規範,不知何故錯過了這個珍聞,但那都得到了。 – 2010-05-23 17:16:22

1

編譯器不會嘗試通過其可見性選擇重載函數或構造函數。

1

即使標記爲私有,編譯器也不會拒絕候選函數。這意味着改變成員的可見性將不會改變現有的代碼。

1

至於你的第二個問題,在測試可見性之前發生重載分辨率。

至於第一個,你需要向編譯器指出0是一個unsigned int。就編譯器而言,從整數0到無符號整數的轉換並不比從整數0到指針的轉換好。