2016-11-30 2 views
3

Dire que j'ai cette fonction:Conversion d'un Functor à un objet de type fonction

template <typename T> 
void foo(function<T(const T&, const T&)> op, const T& lhs, const T& rhs) { 
    cout << op(lhs, rhs) << endl; 
} 

C'est legal code:

function<int(const int&, const int&)> op = plus<int>(); 

foo(op, 13, 42); 

Mais quand je fais ceci:

foo(plus<int>(), 13, 42) 

I obtenir l'erreur:

No matching function for call to foo(std::plus<int>, int, int)

Pourquoi est-ce que je peux initialiser un objet de type function<int(const int&, const int&)> de plus<int>() mais je ne peux pas passer plus<int>() dans un paramètre de type function<T(const T&, const T&)>? Est-ce quelque chose à voir avec le modèle?

+3

Les conversions de type implicite ne fonctionnent pas pendant la déduction d'argument de modèle. – Arunmu

+1

@Arunmu Je pense qu'il existe des exceptions à cette règle: [exemple] (http://melpon.org/wandbox/permlink/ld8NyDotgjK7B7WT) –

+0

@Arunmu C'est la réponse car cela fonctionne si je supprime le modèle: http: // ideone.com/bfjy3p Alors, comment puis-je connaître la conversion entre 'plus ()' et 'la fonction ' est implicite? –

Répondre

2

Je cite la section standard 14.8.1.6:

Implicit conversions (Clause 4) will be performed on a function argument to convert it to the type of the corresponding function parameter if the parameter type contains no template-parameters that participate in template argument deduction.

Cela ne fonctionne pas dans votre cas parce que les paramètres du modèle ont pas été fournies explicitement. Le compilateur doit faire une déduction. Ainsi, comme ci-dessus, il ne fera pas la conversion implicite de foncteur à std::function.

Ainsi, vous pouvez faire (Comme mentionné par @flatmouse dans le commentaire):

foo<int>(plus<int>(), 13, 42);

Cela fonctionne parce qu'il n'y a pas de déduction de l'argument de modèle qui doit être effectuée puisque tous les paramètres du modèle sont explicitement spécifié. Et selon la citation ci-dessus de la norme, la conversion implicite devrait fonctionner pour cela.

+0

Merci pour la citation de la norme, c'est une excellente réponse. Je vais accepter sous peu ... –

+0

Content de vous aider. Merci. – Arunmu