Подтвердить что ты не робот

Лямбда перешла к шаблону, не определенному

Я играл с выводом аргумента шаблона класса С++ 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 может укусить вас в ближайшее время. С другой стороны, как я могу сделать лямбду более определенной, чем она есть, написав ее определение?

4b9b3361

Ответ 1

Мне кажется, что это сбой компилятора. Используя компилятор Clang Visual Studio 2017, генерируется только эта ошибка: "не может ссылаться на шаблон шаблона" foo "без списка аргументов шаблона" для a и b экземпляра в основной функции. Если тип функции указан как параметр шаблона, никаких предупреждений и ошибок нет.

Ответ 2

Недавно я наткнулся на несколько бессмысленных предупреждений, которые смотрели, и пахло, подобно твоему. Я попробовал кучу ручных исправлений с мыслью, что могу заставить линкеры рука (если хотите), но в конце дня я понял, что пытаюсь скомпилировать код С++ 14 с помощью -std=c++17 флаг. Вы можете дважды проверить свои собственные флаги стандартов (и, возможно, соответствующие флаги -stdlib=…).