Страницы

Поиск по вопросам

вторник, 10 декабря 2019 г.

Как правильно описать функцию, что бы в нее можно было передавать функцию, которая имеет пакет параметров

#cpp #шаблоны_с++


Существуют 2 функции

template 
void 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 будет функциональным объектом. #include struct 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)); }

Комментариев нет:

Отправить комментарий