Bonjour,

Je cherche à faire marcher un code du genre :

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
 
template<typename... args>
int func(std::function<int(args...)> f)
{
   return sizeof...(args); // juste pour tester
}
Avec ensuite :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
 
int f2(int a, int b, int c)
{
    return a + b + c;
}
Le code suivant compile bien :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
 
std::function<int(int, int, int)> f3 = f2;
func(f3); // renvoie bien 3
En revanche, celui-ci ne compile pas :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
 
func(f2); /* error: no matching function for call to ‘func(int (&)(int, int, int))’
test.cpp:45:25: note: candidate is:
test.cpp:28:5: note: template<class ... args> int func(std::function<int(args ...)>)
test.cpp:28:5: note:   template argument deduction/substitution failed:
test.cpp:45:25: note:   mismatched types ‘std::function<int(args ...)>’ and ‘int (*)(int, int, int)’ */
Et celui-ci non plus :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
 
func([](int a, int b, int c) { return f2(a,b,c); }); /* error: no matching function for call to ‘func(main()::<lambda(int, int, int)>)’
test.cpp:44:68: note: candidate is:
test.cpp:28:5: note: template<class ... args> int func(std::function<int(args ...)>)
test.cpp:28:5: note:   template argument deduction/substitution failed:
test.cpp:44:68: note:   ‘main()::<lambda(int, int, int)>’ is not derived from ‘std::function<int(args ...)>’ */
Pour le premier cas, je peux fournir un overload :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
 
template<typename... args>
int func(int (*f)(args...))
{
    return sizeof...(args);
}
Pas très élégant, mais ça marche. En revanche, pour le deuxième cas, je ne vois pas comment faire sans fournir l’ensemble des surcharges jusqu’à n arguments, ce qui est justement ce que je souhaitais éviter avec les templates variadic.

Mon compilateur est gcc 4.7.2, je ne peux pas en changer. Des suggestions ?