la raison en est que le compilateur a deux à choisir les surcharges dont chacun utilise trois paramètres . Notez que lors du processus de déduction d'argument, le compilateur déduit les paramètres de modèle participant des arguments d'appel de fonction en regardant indépendamment la paire paramètre/argument.
La déduction d'argument ne réussit que lorsque les paramètres du modèle sont déterminés sans ambiguïté en regardant chaque paire paramètre/argument.Cela signifie que tout en regardant votre deuxième couple paramètre/argument, il dépend (et ne peut pas) du fait que atype1, atype2 et atype3 sont chacun de type 'int', même si vous réarrangez les paramètres du modèle comme
template<class type, class ret, class atype1, class atype2, class atype3>
ret call3(type *pClass, atype1 arg, atype2 arg2, atype3 arg3, ret(type::* funcptr)(atype1, atype2, atype3))
{
//do some stuff here
return (pClass->*funcptr)(arg, arg2, arg3);
}
est ici la citation de la norme qui prend en charge ceci:
les contextes non déduits sont:
- le spécificateur imbriqué nom d'un type qui a été spécifié en utilisant un identifiant qualifié .
- Un argument de modèle non-type ou un groupement lié dans lequel une sous-expression fait référence à un paramètre de modèle.
- Un paramètre de modèle utilisé dans le type d'un paramètre de fonction de paramètres qui a un argument par défaut qui est utilisé dans l'appel pour lequel la déduction des arguments est fait.
- Un paramètre de fonction pour laquelle l'argument déduction ne peut être fait parce que le argument de la fonction associée est une fonction , ou un ensemble de fonctions surchargées (13.4), et un ou plusieurs de les conditions suivantes:
- plus d'une fonction correspondant à la fonction type de paramètre (résultant en une déduction ambiguë ) ou
- pas de fonction correspond au type de paramètre de fonction, ou
- l'ensemble des fonctions fournies comme un argument contient un ou plusieurs modèles de fonction .
maintenant la solution,
Je pense que la seule solution est que vous devrez spécifier explicitement les paramètres du modèle plutôt que de compter sur la déduction des arguments de modèle. Un petit réarrangement des paramètres du modèle aidera
template<class atype1, class atype2, class atype3, class type, class ret>
ret call3(type *pClass, ret(type::* funcptr)(atype1, atype2, atype3), atype1 arg, atype2 arg2, atype3 arg3)
{
//do some stuff here
return (pClass->*funcptr)(arg, arg2, arg3);
}
int main(){
MyClass *a = new MyClass();
call3<int, int, int>(a, &MyClass::test, 1, 2, 3);
}
Lorsque 'ret' est lié à' void', ne se plaint-il pas d'une fonction vide retournant une valeur? –
Aucune plainte pour moi ... Je ne sais pas pourquoi. – jcao219
Renvoyer void à partir d'une fonction renvoyant void est valide, uniquement pour que ce type de casse-bordure soit plus simple dans un code basé sur un modèle. –