據我所知,(MyType)foo
,MyType(foo)
和static_cast<MyType>(foo)
有些類似,前兩個成爲最後一個(編輯:我已經被糾正了,前面的句子是不真實的。)我的問題是哪個是慣用的版本?情境是一個考慮因素?哪種文件static_cast的慣用方式?
因爲我知道C風格轉換在C++中不是首選,所以它可以轉換爲功能轉換和static_cast。
據我所知,(MyType)foo
,MyType(foo)
和static_cast<MyType>(foo)
有些類似,前兩個成爲最後一個(編輯:我已經被糾正了,前面的句子是不真實的。)我的問題是哪個是慣用的版本?情境是一個考慮因素?哪種文件static_cast的慣用方式?
因爲我知道C風格轉換在C++中不是首選,所以它可以轉換爲功能轉換和static_cast。
前兩個,(MyType)foo
和MyType(foo)
,具有相同的含義。含義是什麼取決於MyType
和foo
的類型。因此,例如:
((int)1.0); // a static_cast
int i = 0;
((char*)&i); // a reinterpret_cast
const int j = 0;
((int*)&j); // a const_cast
((char*)&j); // a combination of a const_cast and a reinterpret_cast
typedef char *CharPtr;
CharPtr(&j); // a C-style cast, same as ((CharPtr)&j) or ((char*)&j)
所以C風格的強制類型轉換不理想的原因是,C-風格轉換做很多不同的事情。C++提供了區分它們的手段。在許多情況下,可以更容易地理解代碼,尤其是一旦您使用C++編寫泛型代碼,並且類型不如C中典型代碼明顯。
這就是爲什麼static_cast
等在C++中首選 - 他們明確地爲讀者提供了一些本來難以爲自己解決的問題。順便說一句,static_cast
也會做一些不同的事情,所以原則上你可能會想要更多不同的演員。但是static_cast
至少比C風格演員少。
具有一個參數的功能風格演員陣容是 C型演員陣容。在所有情況下,它們在標準中明確定義爲完全相同的意思。
現在,在某些情況下,如果使用C語言語法編寫函數語法,而不是使用C語言編寫語法,則可能會接受C風格轉換。這通常是目標類型是類的時候,並且很明顯哪個構造函數會被調用。在這種情況下,std::vector<int>(0)
比static_cast<std::vector<int>>(0)
更短,並且通常更清晰,因爲它可以作爲構造函數調用讀取。但它仍然具有與編寫(std::vector<int>)0
相同的「危險」。如果您要以這種方式編寫每次轉換,那麼最終您會不小心從指針類型中刪除const
。
在我的書中使用明確的轉換是慣用的。
static_cast<MyType>(foo)
優於(MyType)foo
,因爲它更具表現力和明確性。這在很多情況下特別有用,其中 不是意味着您期望它的意思。例如,在您的示例中,這些情況可能完全不會減少到static_cast
,而是reinterpret_cast
。
在代碼審查中,我會拒絕所有非算術類型的C風格類型轉換。
我會允許他們算術類型。我不認爲'std :: tolower(static_cast
@SteveJessop:我並沒有真正想到算術類型。我想我多少會同意你的看法。在這種意義上說,'i'的類型未來可能會發生變化,但這似乎有點奇怪。 –
@SteveJessop:對。 –
首先,雖然新的C++,功能風格演員是 C風格演員。他們做同樣的事情。
C型表演首先嚐試到static_cast
,如果這不起作用,請執行reinterpret_cast
。這很糟糕,因爲旨在進行簡單更改的操作可能會變得非常奇怪。
舉一個例子,假設你有一個Foo* f
和一個完全不相關的類Bar
。您可以(Bar*)f
,它會默默重新解釋*f
爲Bar
,可能導致未定義的行爲。
如果Foo
和Bar
是相關類型,A static_cast
只適用於此情況。
現在,即使static_cast
可能太強大了,所以我經常寫一個implicit_cast
或non_cast
模板,它可以轉換而不需要轉換。同樣,我寫as_const
,它增加const
而不是要求const_cast
(它既可以添加也可以刪除const
,並且刪除const
比添加它更危險)。
這是有點惱人的,有在C++中沒有明確的安全投了,我不知道如何寫一個(一個將執行explicit
構造函數,但不會投「向下」類型層次結構像static_cast
會)。
這是一個過於簡單化,但足夠接近真實。
「在C++中沒有明確的安全轉換」 - 嗯。在兩個模板參數都是指針類型和(在remove_pointer之後)源是目標的基礎的情況下,執行'static_cast'並禁用的模板函數? –
@SteveJessop「向上」指針轉換也是安全的,所以雅。 SFINAE可能會工作。這是否抓住每一個案例? – Yakk
順便說一句,「C++ explicit_cast」的網頁搜索引導我在那裏:http://stackoverflow.com/questions/5693432/making-auto-cast-safe(簡而言之,C++ 11統一初始化和'std :: is_constructible '被喚起) –
http://stackoverflow.com/questions/103512/in-c-why-use-static-castintx-instead-of-intx – aardvarkk
不,這些*不*相同。例如,第一個變爲'reinterpret_cast',而不是'static_cast'。 – dasblinkenlight
事實上,你可以grep'static_cast'使它成爲我眼中的贏家。 – molbdnilo