Лямбда перешла к шаблону, не определенному
Я играл с выводом аргумента шаблона класса С++ 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 может укусить вас в ближайшее время. С другой стороны, как я могу сделать лямбду более определенной, чем она есть, написав ее определение?
Ответы
Ответ 1
Мне кажется, что это сбой компилятора. Используя компилятор Clang Visual Studio 2017, генерируется только эта ошибка: "не может ссылаться на шаблон шаблона" foo "без списка аргументов шаблона" для a и b экземпляра в основной функции. Если тип функции указан как параметр шаблона, никаких предупреждений и ошибок нет.
Ответ 2
Недавно я наткнулся на несколько бессмысленных предупреждений, которые смотрели, и пахло, подобно твоему. Я попробовал кучу ручных исправлений с мыслью, что могу заставить линкеры рука (если хотите), но в конце дня я понял, что пытаюсь скомпилировать код С++ 14 с помощью -std=c++17
флаг. Вы можете дважды проверить свои собственные флаги стандартов (и, возможно, соответствующие флаги -stdlib=…
).