#cpp #шаблоны_с++
Существуют 2 функции templatevoid print(Argc ... argv) { std::cout << sizeof...(argv) << " "; } template void run(F f(Arrr...) ) { f(1, 2, 3, 4, 5); } При вызове run(print); gcc выводит такую ошибку /home/eugeniy/CLionProjects/myfirsproject/main.cpp: In function ‘int main()’: /home/eugeniy/CLionProjects/myfirsproject/main.cpp:782:14: error: no matching function for call to ‘run( )’ run(print); ^ /home/eugeniy/CLionProjects/myfirsproject/main.cpp:571:6: note: candidate: template void run(F (*)(Arrr ...)) void run(F f(Arrr...) ) ^ /home/eugeniy/CLionProjects/myfirsproject/main.cpp:571:6: note: template argument deduction/substitution failed: /home/eugeniy/CLionProjects/myfirsproject/main.cpp:782:14: note: couldn't deduce template parameter ‘F’ run(print); ^ Вопрос: Как мне надо объявить функцию run, что бы вызов run(print) работал корректно?
Ответы
Ответ 1
Что-то похожее можно сделать, если print будет функциональным объектом. #includestruct print_t { template void operator()(Argc ... argv) { std::cout << sizeof...(argv) << " "; } }; constexpr print_t print; template void run(F f) { f(1, 2, 3, 4, 5); } int main() { run(print); } Ответ 2
Никак. При передаче адреса шаблона функции в другую функцию в качестве параметра нужно знать, какая именно её реализация будет использована. То есть на этапе компиляции нужно выяснить, run принимает void(*)(int) или void(*)(float, Foo). Вывести подобную информацию, анализируя код функции run, компилятор не может, так как это не поддерживается стандартом языка. Другое дело - использовать абсолютно логичный вариант @Abyx, который позволяет передать объект некоторого класса в run, тип которого будет известен во время компиляции, а уже внутри run будет вызвана одна из реализаций шаблонного оператора operator()(Args...). Чтобы не писать для всех шаблонных функций много кода, а использовать run напрямую (почти), можно сделать следующим образом: #define pass(func) [](auto&&... args) -> decltype(func(std::forward(args)...)) { return func(std::forward (args)...); } и использовать run так: template void run(F f) { f(1, 2, 3, 4, 5); } int main() { run(pass(print)); }
Комментариев нет:
Отправить комментарий