Si vous avez besoin du type de quelque chose qui ne ressemble pas à un appel de fonction, std::result_ofcela ne s'applique tout simplement pas. decltype()peut vous donner le type de n'importe quelle expression.
Si nous nous limitons aux différentes manières de déterminer le type de retour d'un appel de fonction (entre std::result_of_t<F(Args...)>et decltype(std::declval<F>()(std::declval<Args>()...)), alors il y a une différence.
std::result_of<F(Args...) est défini comme:
  Si l'expression
   INVOKE (declval<Fn>(), declval<ArgTypes>()...)est bien formée lorsqu'elle est traitée comme un opérande non évalué (clause 5), le type typedef membre doit nommer le typedecltype(INVOKE (declval<Fn>(), declval<ArgTypes>()...)); 
  sinon, il n'y aura pas de type de membre.
La différence entre result_of<F(Args..)>::typeet decltype(std::declval<F>()(std::declval<Args>()...)est tout à propos de cela INVOKE. L'utilisation de declval/ decltypedirectement, en plus d'être un peu plus longue à taper, n'est valide que si elle Fest directement appelable (un type d'objet fonction ou une fonction ou un pointeur de fonction).result_ofprend également en charge les pointeurs vers les fonctions des membres et les pointeurs vers les données des membres.
Initialement, utiliser declval/ decltypegaranti une expression compatible SFINAE, alors que cela std::result_ofpourrait vous donner une erreur matérielle au lieu d'un échec de déduction. Cela a été corrigé en C ++ 14: std::result_ofdoit maintenant être compatible avec SFINAE (grâce à ce papier ).
Donc, sur un compilateur C ++ 14 conforme, std::result_of_t<F(Args...)>c'est strictement supérieur. C'est plus clair, plus court et correctement † prend en charge plus de Fs ‡ .
† À moins que vous ne l'utilisiez dans un contexte où vous ne souhaitez pas autoriser les pointeurs vers les membres, cela 
std::result_of_tréussirait dans un cas où vous pourriez souhaiter qu'il échoue.
‡ Sauf exceptions. Bien qu'il prenne en charge les pointeurs vers les membres, result_ofne fonctionnera pas si vous essayez d'instancier un type-id non valide . Celles-ci incluraient une fonction renvoyant une fonction ou prenant des types abstraits par valeur. Ex.:
template <class F, class R = result_of_t<F()>>
R call(F& f) { return f(); }
int answer() { return 42; }
call(answer); // nope
L'utilisation correcte aurait été result_of_t<F&()>, mais c'est un détail dont vous n'avez pas à vous souvenir decltype.
               
              
decltypesache, c'est plus laid mais aussi plus puissant.result_ofne peut être utilisé que pour les types appelables et nécessite des types comme arguments. Par exemple, vous ne pouvez pas utiliserresult_ofici:template <typename T, typename U> auto sum( T t, U u ) -> decltype( t + u );si les arguments peuvent être des types arithmétiques (il n'y a pas de fonctionFtelle que vous pouvez définirF(T,U)pour représentert+u. Pour les types définis par l'utilisateur, vous pouvez. De la même manière (je n'ai pas vraiment joué avec) j'imagine que les appels aux méthodes membres peuvent être difficiles à faireresult_ofsans utiliser de liants ou de lambdas