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 decltype
coisa 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 a
e b
está no decltype
argumento. Isso ocorre porque eles são declarados apenas pela lista de argumentos.
Você poderia solucionar o problema facilmente usando declval
os 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 return
instruçõ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.