这是我写的关于 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++ 都会生成编译器错误。)