No C ++ 11, existem duas sintaxes para declaração de função:
identificador de tipo retorno ( declarações-argumento ... )
e
auto identificador ( argumento-declarações ... ) -> return_type
Eles são equivalentes. Agora, quando são equivalentes, por que você deseja usar o último? Bem, o C ++ 11 introduziu essa decltypecoisa interessante que permite descrever o tipo de uma expressão. Portanto, você pode derivar o tipo de retorno dos tipos de argumento. Então você tenta:
template <typename T1, typename T2>
decltype(a + b) compose(T1 a, T2 b);
e o compilador lhe dirá que ele não sabe o que ae bestá no decltypeargumento. Isso ocorre porque eles são declarados apenas pela lista de argumentos.
Você poderia solucionar o problema facilmente usando declvalos parâmetros de modelo que já foram declarados. Gostar:
template <typename T1, typename T2>
decltype(std::declval<T1>() + std::declval<T2>())
compose(T1 a, T2 b);
exceto que está ficando muito detalhado agora. Portanto, a sintaxe da declaração alternativa foi proposta e implementada e agora você pode escrever
template <typename T1, typename T2>
auto compose(T1 a, T2 b) -> decltype(a + b);
e é menos detalhado e as regras de escopo não precisam ser alteradas.
Atualização do C ++ 14: o C ++ 14 também permite apenas
auto identificador ( argumento-declarações ... )
desde que a função esteja totalmente definida antes do uso e todas as returninstruções sejam deduzidas para o mesmo tipo. A ->sintaxe permanece útil para funções públicas (declaradas no cabeçalho) se você deseja ocultar o corpo no arquivo de origem. Obviamente, isso não pode ser feito com modelos, mas existem alguns tipos concretos (geralmente derivados da metaprogramação de modelos) que são difíceis de escrever de outra forma.