這是我寫的關於 C++0x 字尾返回型別的文章。它也釋出在
我的部落格 (SFML Coder) 上。 如果您有任何更正或改進的建議,請私信我或
給我發郵件! 感謝
jsmith 提供了比我原來的例子更合適的例子。
現在開始介紹另一個小的 C++0x 特性。 像
auto 一樣,它受 Microsoft Visual C++ 2010 和 MinGW 支援。 如果您有不同的編譯器,那麼嘗試一下也沒什麼壞處。 請記住,如果您遇到編譯器錯誤,則可能意味著您的編譯器不支援該功能。
讓我們用一個例子直奔主題。 考慮以下我們通常如何編寫函式的示例
1 2 3 4 5
|
bool Init()
{
// etc
return true;
}
|
這是使用尾隨返回型別的方式
1 2 3 4 5
|
auto Init() -> bool
{
// etc
return true;
}
|
我們為什麼要這樣做? 畢竟,這需要做更多的工作。 好了,是的,在這種情況下需要做更多的工作,但是現在考慮一個真實的例子。 在我的遊戲引擎日誌中,我有一個函式,它接受一個字串,對其應用一些格式並返回它。 字串型別是
typedef
'd
std::string
稱為
String
在
Icanos::System
名稱空間中。
這就是我利用此 C++0x 特性之前編寫函式的方式。
1 2 3 4
|
Icanos::System::String Icanos::System::FormattedLog::ApplyIndent(const String& message, const String& source)
{
// etc
}
|
我必須完全限定
String
返回型別。 但是,如果我可以將返回型別放在後面,那麼 String 型別將已經在作用域內,因為我們已經限定了函式的作用域,從而簡化了表示法。
1 2 3 4
|
auto Icanos::System::FormattedLog::ApplyIndent(const String& message, const String& source) -> String
{
// etc
}
|
在函式名稱之後,
Icanos::System
中的所有內容已經在作用域中,因此我們無需再次限定
String
上的名稱空間。
現在,如果我們的返回型別依賴於引數型別(在模板函式中),我們可能還需要使用字尾返回型別。
感謝 jsmith 的補充。天真地,我們應該喜歡這樣做
1 2
|
template <class S, class T>
decltype(s + t) Add(const S& s, const T& t)
|
當然,它不會編譯,因為
s 和
t 不在作用域內。 但是它們在引數列表之後才在作用域內
1 2
|
template <class S, class T>
auto Add(const S& s, const T& t) -> decltype(s + t)
|
這是解決此問題的一種好方法,僅供您參考,這是 Stroustrup 在沒有後綴返回型別的情況下提出的較小惡魔的版本。 它顯然是劣等的。
1 2
|
template <class S, class T>
decltype(*(S*)(0) + *(T*)(0)) Add(const S& s, const T& t)
|
好了,希望您喜歡我對字尾返回型別的介紹 - 您也可能看到它被稱為尾隨返回型別。 如果您想了解更多資訊,請檢視 Dr. Stroustrup 的 FAQ
http://www2.research.att.com/~bs/C++0xFAQ.html#suffix-return
(巧合的是,最初建議(如 Stroustrup 的 FAQ 中所述)字尾返回型別使用 [] 而不是 auto 來表示。 但是,由於爭議,建議使用 auto 作為替代方法。 如果使用 [],則 MinGW 和 Microsoft Visual C++ 都會生成編譯器錯誤。)