Следующий код не будет собран, будем признательны за любые отзывы о причине.
void bar(std::string str, int& a, int& b)
{
}
template<typename T, typename ... Args>
void foo(std::function<void(T, Args...)> fcn, Args ... args)
{
// Some code that calls fcn
}
void run()
{
int a = 3;
int b = 5;
foo<std::string, int&, int&>(bar, a, b);
}
Это модифицированная реализация первого решения, предложенного в этом ТАК-ответе.
IDE выдает следующую ошибку при вызове строки foo:
Шаблон C++<class T, class... Args> void foo(std::function<void (T, Args...)> fcn, Args ...args)
ни один экземпляр шаблона функции «foo» не соответствует списку аргументов
типы аргументов:
(void (std::string str, int &a, int &b), int, int)
Протестировано отдельно, кажется, что передача аргумента fcn с аргументами шаблона — это нормально. Проблема, по-видимому, заключается в передаче аргумента функции, где функция может принимать аргументы шаблона с переменным числом аргументов.





Функция (указатель) не является std::function, поэтому не работает для вывода.
В этом контексте вы можете сделать Ts... невыводимым.
template<typename T, typename ... Args>
void foo(std::function<void(T, std::type_identity_t<Args>...)> fcn, Args ... args)
{
// Some code that calls fcn
}
или отбросьте std::function полностью
template<typename T, typename F, typename ... Args>
requires (std::is_invocable<F, T, Args...>::value)
void foo(F fcn, Args&& ... args)
{
// Some code that calls fcn
}
То же самое справедливо и для std::is_invocable. Оба ответа приветствуются, несмотря ни на что.
Но вычет не происходит, если указаны аргументы шаблона.
Использование requires можно заменить на auto foo(F f, Args&&... args) -> decltype(f(std::declval<T>(), std::forward<Ts>(args)...), void())
@DavidG: Мы указываем начало, мы не можем сказать, что остановка пакета, т. е. с template <typename... Ts> void bar(std::tuple<Ts...>); bar<int>(std::tuple<int, char, float>{}) действительна.
#include <iostream>
#include <functional>
void bar(std::string str, int a, int b)
{
}
template<typename T, typename ... Args>
void foo(std::function<void(T, Args...)> fcn, Args ... args)
{
// Some code that calls fcn
}
int main() {
std::function<void(std::string, int, int)> func_1 = bar;
int a = 3;
int b = 5;
foo(func_1, a, b);
return 0;
}
#include <iostream>
#include <functional>
void bar(std::string str, int* a, int* b)
{
}
template<typename T, typename ... Args>
void foo(std::function<void(T, Args...)> fcn, Args ... args)
{
// Some code that calls fcn
}
int main() {
std::function<void(std::string, int*, int*)> func_1 = bar;
int a = 3;
int b = 5;
foo(func_1, &a, &b);
return 0;
}
Отлично, спасибо. Линия func_1 очень помогает.
Спасибо всем. Судя по ответу от Серкана, кажется, работает следующее.
#include <iostream>
#include <functional>
void bar(std::string str, int& a, int& b)
{
}
template<typename T, typename ... Args>
void foo(std::function<void(T, Args...)> fcn, Args ... args)
{
// Some code that calls fcn
}
int main() {
std::function<void(std::string, std::reference_wrapper<int>, std::reference_wrapper<int>)> func_1 = bar;
int a = 3;
int b = 5;
foo(func_1, std::ref(a), std::ref(b));
foo((std::function<void(std::string, std::reference_wrapper<int>, std::reference_wrapper<int>)>)bar, std::ref(a), std::ref(b));
return 0;
}
Я проведу еще тесты, возможно, еще потребуются некоторые изменения.
Спасибо! Есть ли обходной путь, который не требует С++ 20? Кажется,
type_identityбыл добавлен в C++20.