Going to post this article about C++0x suffix return types on my blog later, and I thought I'd put it here too. I'm guessing most of the readers of the article section already know it - if so then hopefully you can help me iron out any mistakes :)
From SFMLCoder:
http://sfmlcoder.wordpress.com/
-------------------------------------------------------------------------------
Time for another little C++0x feature. Like
auto, it is supported by Microsoft Visual C++ 2010 and MinGW. If you have a different compiler, then you can't go wrong by trying it anyway. Just remember that if you get compiler errors, it could mean the feature isn't supported by your compiler.
Let's get straight to it with an example. Consider the following example of how we would normally code a function:
1 2 3 4 5
|
bool Init()
{
// etc
return true;
}
| |
And here is the way using trailing return types:
1 2 3 4 5
|
auto Init() -> bool
{
// etc
return true;
}
| |
Why would we want to do this? It's more work after all. Well yes, it is more work in this case, but now consider a real world example. In my game engine's log, I have a function which takes a string, applies some formatting to it and returns it. The string type is a
typedef
'd
std::string
called
String
in the
Icanos::System
namespace.
This is how I had written the function before I took advantage of this C++0x feature.
1 2 3 4
|
Icanos::System::String Icanos::System::FormattedLog::ApplyIndent(const String& message, const String& source)
{
// etc
}
| |
I have to qualify the
String
return type in full. But if I could put the return type after, the String type would already be in scope as we've qualified the function's scope, thus simplifying notation.
1 2 3 4
|
auto Icanos::System::FormattedLog::ApplyIndent(const String& message, const String& source) -> String
{
// etc
}
| |
After the function name, everything in
Icanos::System
is already in scope, so we don't need to qualify the namespaces on
String
again.
Now then, we might also want to use suffix return types if our return type depends on the argument types (in a template function).
Thanks to jsmith for this addition.
Naively, we should like to do this:
1 2
|
template <class S, class T>
decltype(s + t) Add(const S& s, const T& t)
| |
but of course, it will not compile, as
s and
t are not in scope. But they are in scope after the parameter list:
1 2
|
template <class S, class T>
auto Add(const S& s, const T& t) -> decltype(s + t)
| |
This is a neat way of solving this problem, and just for your reference, here is the version Stroustrup suggests in the absence of suffix return types. It is clearly inferior.
1 2
|
template <class S, class T>
decltype(*(S*)(0) + *(T*)(0)) Add(const S& s, const T& t)
| |
Well I hope you've enjoyed my introduction to suffix return types - which you may also see referred to as trailing return types. If you'd like to read more about them, check out Dr. Stroustrup's FAQ:
http://www2.research.att.com/~bs/C++0xFAQ.html#suffix-return
(Coincidentally, it was originally suggested (as noted in Stroustrup's FAQ) that suffix return types be signified using [] rather than auto. However, due to controversy, auto is suggested as an alternative. Both MinGW and Microsoft Visual C++ generate a compiler error if [] is used.)