In C ++ 11, there are two syntaxes for declaring a function:
return type identifier ( declaration argument ... )
and
auto identifier ( declaration-argument ... ) -> return_type
They are equivalent. Now that they are equivalent, why do you ever want to use the latter? So, C ++ 11 introduced this cool decltype thing that lets you describe the type of expression. That way you can get the return type from the argument types. So you are trying:
template <typename T1, typename T2> decltype(a + b) compose(T1 a, T2 b);
and the compiler will tell you that it does not know that a and b are in the decltype argument. This is because they are declared only in the argument list.
You can easily solve the problem using declval and template parameters that are already declared. How:
template <typename T1, typename T2> decltype(std::declval<T1>() + std::declval<T2>()) compose(T1 a, T2 b);
with the exception that now it becomes really verbose. Therefore, the syntax of an alternative declaration was proposed and implemented, and now you can write
template <typename T1, typename T2> auto compose(T1 a, T2 b) -> decltype(a + b);
and it is less detailed, and the rules for determining the field of view do not need to be changed.
C ++ 14 Update: C ++ 14 also makes it easy
auto identifier ( declaration argument ... )
while the function is fully defined before use, and all return are inferred into the same type. The -> syntax remains useful for public functions (declared in the header) if you want to hide the body in the source file. Most likely, this cannot be done using templates, but there are some specific types (usually obtained through metaprogramming of templates) that are difficult to write otherwise.