Je jouais aujourd'hui avec la déduction des arguments des modèles de classe de C++17. La première idée évidente qui m'est venue à l'esprit était de passer un callable comme paramètre de modèle. Un callable, c'est entre autres un lambda, pourquoi pas. Essayons cela.
template<typename F> class foo
{
F f;
public:
foo(F in) : f(in) { f(); /* not very useful, admitted */ }
};
void bar() { puts("a"); }
int main()
{
auto a = foo(bar);
auto b = foo([](){ puts("b"); });
return (void) a, (void) b, 0;
}
Voici ce que clang (5.0, r300688) a à dire à ce sujet :
warning : la fonction '<(lambda at [source location])>' a un lien interne mais n'est pas définie.
Le code se compile et "fonctionne bien", mais l'avertissement suggère que le compilateur n'est pas tout à fait satisfait.
Je suis prêt à accepter que le lambda a un lien interne (étant anonyme il n'est pas accessible ailleurs dans la même unité de traduction, donc bien sûr il est inaccessible dans une autre), mais qu'en est-il. I ne veulent pas y accéder à partir d'une autre unité de traduction.
La partie concernant l'absence de définition me fait rire, je ne saurais même pas comment écrire un lambda sans le définir.
En résumé : Que se passe-t-il ? Que penser de tout cela ? Je n'aime pas les avertissements, non seulement ils rendent le build moins joli, mais ils généralement signifie que quelque chose ne va pas et qu'un comportement indéfini risque de vous mordre bientôt. D'un autre côté, comment puis-je faire un lambda plus défini qu'elle ne l'est déjà en écrivant sa définition ?