2012-03-04 34 views
1

爲什麼這個代碼(未分配的臨時變量從一個const char *變量構造的)?爲什麼當這個類有一個const char *構造函數時,用const char *變量構造一個未分配的類臨時實例會出錯?</p> <pre><code>class A { public: A(const char*) {} }; int main() { const char* constCharPointerVariable = "StringLiteral"; A(constCharPointerVariable); return 0; } </code></pre> <p>給這些錯誤:

error C2512: 'A' : no appropriate default constructor available 
error C2040: 'constCharPointerVariable' : 'A' differs in levels of indirection from 'const char *' 

鑑於這個代碼(從一個const char *變量構成分配的臨時變量):

class A 
{ 
public: 
    A(const char*) {} 
}; 

int main() 
{ 
    const char* constCharPointerVariable = "StringLiteral"; 
    A a(constCharPointerVariable); 
    return 0; 
} 

給出任何錯誤。

而這個代碼(從一個const char構造未分配的臨時變量*變量的static_cast到一個const char *):

class A 
{ 
public: 
    A(const char*) {} 
}; 

int main() 
{ 
    const char* constCharPointerVariable = "StringLiteral"; 
    A(static_cast<const char*>(constCharPointerVariable)); 
    return 0; 
} 

給出任何錯誤。

如果您可以在C++規範中提供指定不允許的第一個代碼示例的部分編號,則爲獎勵分數。

回答

7
A(constCharPointerVariable); 

這實際上是一個名爲constCharPointerVariableA類型的變量的聲明。它不創建臨時對象。

如果使用鐺,你會得到更多有用的錯誤信息:

error: redefinition of 'constCharPointerVariable' with a different type 
    A(constCharPointerVariable); 
    ^

作爲一個簡單的例子,下面是無效的,因爲它宣稱在同一域內的兩個int對象,並重命名x

int x(0); 
int (x); 

至於爲什麼代碼解析這種方式,你可以找到說明符的語法規則§A.7的 11 C++。基本上,當你聲明一個變量時,你可以用任意數量的括號括起它的名字。

相關作品包括:

  • 聲明符 - >PTR說明符
  • PTR說明符 - >noptr說明符 | 聲明符-ID
  • noptr說明符 - >(PTR說明符)
+0

+1 - 怎麼沒有人記得這一切的東西...?請注意,圍繞整個事物的parens將把它變成一個表達式,使它成爲可能。我猜這是一件好事,我們並不經常希望表達式只是一個臨時對象(儘管我可以看到一個可能的,如果不太可能的話,用於RAII類)。 – 2012-03-04 00:16:35

+0

@MichaelBurr:無論如何,這將是糟糕的課程設計。如果你想要一些只做一次的事情,你應該把它變成一個*函數*。 – 2012-03-04 00:20:08

+0

謝謝詹姆斯,我沒有意識到這種語法。您的回答是我第二次聽說過鏗鏘有力的錯誤消息。第一次來自微軟的這次演講:http://channel9.msdn.com/Events/GoingNative/GoingNative-2012/Clang-Defending-C-from-Murphy-s-Million-Monkeys – 2012-03-04 00:32:08

相關問題