2016-08-29 18 views
13

這個問題涉及到我在C++規範中注意到的情況,當時我試圖回答this earlier, intriguing question about C-style casts and type conversionsC++規範是否說明了如何在static_cast/const_cast鏈中選擇類型以用於C風格轉換?

C++規範談到了§ 5.4中的C風格演員。它說,中投符號將嘗試以下鑄件,順序,直到一個發現是有效的:通過const_cast

  • reinterpret_cast
  • reinterpret_cast

    • const_cast
    • static_cast
    • static_cast其次其次是const_cast

    雖然我意味着什麼使用static_cast接着是const_cast一個偉大的直觀的想法(例如,一個const Derived*Base*通過一個const_cast<Base*>(static_cast<const Base*>(expr))去轉換),我沒有看到任何字眼在說明中,具體說明如何推導static_cast/const_cast系列中使用的類型。在簡單指針的情況下並不那麼難,但正如在鏈接問題中所看到的,如果在一個地方引入額外的const並將其從另一個地方移除,則該投射可能成功。

    是否有任何規則來控制編譯器如何確定在鑄造鏈中使用哪些類型?如果是這樣,他們在哪裏?如果不是,這是語言的缺陷,還是有足夠的隱含規則來唯一確定所有可能的演員陣容?

  • 回答

    3

    如果不是,這是語言中的缺陷,還是有足夠的隱式規則來唯一確定所有可能的演員陣容?

    那麼只用const_cast即所有的「中間類型」構造所有可以轉換成目標類型的類型呢?

    定目標類型T,如果static_cast不工作,確定所有位置,其中一個可以添加cv修飾符使得所產生的類型可以通過const_cast 強制轉換回T。該算法的草圖:採取cv分解([conv.qual]/1T;每個cv j可以被增強。如果T是參考,我們可以增加裁判類型的cv資格。

    現在將const volatile添加到所有這些地方。調用結果類型CT。改爲將static_cast的表達式改爲CT。如果可行,我們的演員鏈是const_cast<T>(static_cast<CT>(e))

    如果這不起作用,很可能是沒有轉換使用static_cast其次是const_cast(我還沒有深入探討重載解決方案的深角(以及我有,但不是這個問題))。但是我們可以使用蠻力重複刪除const/volatile s,並檢查每種類型,如果我們真的想要。所以從理論上講,沒有含糊不清或者說不清楚的地方;如果有一些鑄造鏈,則可以確定。在實踐中,該算法可以變得非常簡單,因爲我們可以從T構建的「最合適的CV」類型(確定地)是足夠的。