2010-12-08 50 views
3

根據標準(第5.2.11節),一個const_cast將cv-qualifiers(const或volatile)轉換掉。爲什麼const_cast需要說明你要投射的內容?

下面是一個簡單的例子。首先聲明兩個函數採用指針和參考:使用適當的const_cast

Bar b; 
const Bar& cb = b; 

,然後你可以調用函數:

class Bar { ... }; 
void foo_ptr(Bar*); 
void foo_ref(Bar&); 

然後創建一個參考給const

foo_ptr(const_cast<Bar*>(&cb)); 
foo_ref(const_cast<Bar&>(cb)); 

這是我的問題:因爲const_cast無法完成其他演員設計的內容,所以您投射的內容不是很明顯嗎?換句話說,爲什麼不語讓我簡單地說:

foo_ptr(const_cast<>(&cb)); 
foo_ref(const_cast<>(cb)); 

我能想到的只有以下兩個原因:

一)編譯器應該停止我,當我嘗試做一些發瘋一樣:

foo_ptr(const_cast<int*>(&cb)); 
foo_ref(const_cast<int&>(cb)); 

並迫使我明確指出我鑄造它,然後可以讓我從行爲不端的類型。我覺得這個(假設的)解釋很弱,因爲如果語言傾向於讓我寫下錯誤只是爲了讓編譯器糾正我,那將是很奇怪的。

b)如果變量既是常量又是易失性的,則可能存在歧義。在這種情況下,編譯器將無法告訴我是否試圖拋棄這一個或另一個(或兩者)。

這是爲什麼,還是有其他原因?

回答

5

const_cast可用於添加或刪除constvolatile限定符。所以,如果這樣的語法被允許,以下所有的將是const_cast<>(&cb)合法目標類型:

Bar*     (1) 
const Bar*   (2) 
volatile Bar*  (3) 
const volatile Bar* (4) 

您打算(1)(2)通常很愚蠢,但可以想象,它可能發生在某處,也許在某些模板代碼中。 (3)(4)的確存在以下問題:您可以刪除const資格,並將所有資格都添加到單個演員表中。

你可以用一對石膏,const_castvolatile_cast和的取代現有const_cast,和禁止的情況下(2);那麼你可以使用它們中的任何一個而不使用目標類型。然而,知道演員表達的類型則更加困難。要知道演員表達式是否添加或刪除限定條件,您必須知道源表達式的類型。

沒有理由你不能使用函數模板來獲得你想要的東西:

template <typename T> 
T* remove_const(const T* p) { 
    return const_cast<T*>(p); 
} 

你可以很容易地編寫remove_volatileadd_constadd_volatile類似的功能,這兩者都是隱含的。

+0

當然,該運算符還允許`const_cast <>(&b)`(其中b不是`const')和相同的結果類型集合,所以即使它沒有處理波動性,您也必須問Alexandros無論const_cast <>是否應該切換常量或默認添加或刪除它(後者會使它有點用詞不當)。正如你所說,在模板中,通常需要在不知道開始的情況下獲得const或非const類型。 – 2010-12-08 03:07:21

+0

@Tony:關於b不需要是const的好處。更一般地說,儘管我知道const_cast也可以添加const,但我的隱含假設是沒有人這樣做(因爲還有其他方法可以這樣做),因此如果輸入b不是const,那麼就讓它成爲。 – 2010-12-08 03:22:35

1

我認爲詹姆斯麥克奈利斯已經談到了重要的原因。 const_cast都可以並刪除常量/不穩定性。這並不總是清楚你想要什麼。

如果我打電話const_castconst foo類型的參數,這是否意味着我想讓它不const,或添加volatile呢?或者它應該只是保留const限定符?如果我在類型(非const)foo的對象上調用它,它應該添加const嗎?還是應該假設我想刪除常量,並返回一個類型爲(非常量)foo的對象呢?

另一個原因可能只是一致性。

我們有static_cast<T>(x),dynamic_cast<T>(x),reinterpret_cast<T>(x)所以如果沒有類似於模板的語法就有const_cast(x),看起來很奇怪。

0

的主要原因是使用const_cast你可以從

Foo * const * volatile * * 

轉換爲

Foo * * * volatile * const 

是否真的明顯的目標類型是什麼?