Published by
Jun 15, 2011 (last update: Jun 23, 2011)

C++0x Suffix Return Types

Score: 3.8/5 (92 votes)
*****
This is an article I have written on the C++0x suffix return type. It is also posted on my blog (SFML Coder). If you have any suggestions for correction or improvement, PM me or email me! Thanks to jsmith who suggested a more apt example than my original.



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 presents as the lesser of evils in the absense 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.)