Почему происходит следующее [?]
Учтите, что при вызове
foo0<void, int>(bar); // compilation error
foo1<void, int>(bar); // compile
foo0()
и foo1()
ожидают std::function
и bar
- это указатель на функцию, которая может быть преобразована в std::function
, но не является std::function
.
В случае foo1()
вы явно указываете как RetType
, так иArgType
параметров шаблона, так что компилятор может преобразовать bar
в std::function<void(int)>
, и все идет хорошо.
Но случай foo0()
отличается, поскольку параметр шаблона ArgTypes...
является переменным ипри вызове foo0<void, int>(bar)
вы не указываете полный список ArgTypes...
variadic, а только первый тип.
Если я не ошибаюсь, проблема в том, что компилятор пытается вывести остальную часть ArgTypes...
из аргумента bar
, но bar
не является std::function
, поэтому компилятор не может вывести остальную часть ArgTypes...
, поэтому ошибка.
Я полагаю, что
foo0<void, int>(std::function<void(int)>{bar});
или просто
foo0(std::function<void(int)>{bar});
или (только C ++ 17) также
foo0(std::function{bar});
должны компилироваться, потому что, вызывая foo0()
таким образом, функция получилаea std::function
чтобы компилятор мог полностью определить параметры шаблона.
Я не понимаю, как версия с bar()
с фиктивным параметром шаблона
foo0<void, int>(bar<int>);
может компилироваться с g ++-8 и я предполагаю, что это ошибка g ++.