Я играл с выводом аргумента шаблона класса С++ 17 сегодня. Первая очевидная идея, которая пришла на ум, заключалась в передаче параметра шаблона. Вызываемый, что среди прочего лямбда, почему бы и нет. Попробуйте это.
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;
}
Вот что говорит clang (5.0, r300688):
warning: function '< (lambda at [source location]) > 'имеет внутреннюю связь, но не определен
Код компилируется и, безусловно, "отлично работает", но предупреждение говорит о том, что компилятор ему не совсем удовлетворен.
Я готов согласиться с тем, что лямбда имеет внутреннюю связь (будучи анонимной, недоступной нигде в одной и той же единицы перевода, поэтому достаточно уверенно, что она недоступна в другой), но что с ней делать. Я не хочу получать доступ к нему из другой единицы перевода. Часть, касающаяся отсутствия определения, кажется мне забавной, я даже не знаю, как написать лямбда, не определяя ее.
Вкратце: что дает? Что с этим делать? Мне не нравятся предупреждения, они не только делают сборку менее симпатичной, но они обычно означают, что что-то не так, а поведение типа undefined может укусить вас в ближайшее время. С другой стороны, как я могу сделать лямбду более определенной, чем она есть, написав ее определение?