web-dev-qa-db-fra.com

Différence entre std :: result_of et decltype

J'ai du mal à comprendre la nécessité de std::result_of en C++ 0x. Si j'ai bien compris, result_of est utilisé pour obtenir le type résultant d'invocation d'un objet fonction avec certains types de paramètres. Par exemple:

template <typename F, typename Arg>
typename std::result_of<F(Arg)>::type
invoke(F f, Arg a)
{
    return f(a);
}

Je ne vois pas vraiment la différence avec le code suivant:

template <typename F, typename Arg>
auto invoke(F f, Arg a) -> decltype(f(a)) //uses the f parameter
{
    return f(a);
}

ou

template <typename F, typename Arg>
auto invoke(F f, Arg a) -> decltype(F()(a)); //"constructs" an F
{
    return f(a);
}

Le seul problème que je peux voir avec ces deux solutions est que nous devons:

  • avoir une instance du foncteur pour l'utiliser dans l'expression passée à decltype.
  • connaître un constructeur défini pour le foncteur.

Ai-je raison de penser que la seule différence entre decltype et result_of est-ce que le premier a besoin d'une expression alors que le second n'en a pas?

96
Luc Touraille

result_of était introduit dans Boost , puis inclus dans TR1 , et enfin en C++ 0x. Par conséquent result_of a un avantage qui est rétrocompatible (avec une bibliothèque appropriée).

decltype est une chose entièrement nouvelle en C++ 0x, ne se limite pas uniquement au retour du type d'une fonction, et est une fonctionnalité de langage.


Quoi qu'il en soit, sur gcc 4.5, result_of est implémenté en termes de decltype:

  template<typename _Signature>
    class result_of;

  template<typename _Functor, typename... _ArgTypes>
    struct result_of<_Functor(_ArgTypes...)>
    {
      typedef
        decltype( std::declval<_Functor>()(std::declval<_ArgTypes>()...) )
        type;
    };
84
kennytm