Приветствую!
Есть такая задача - протащить некий функтор с переменным количеством аргументов в std::function<void()>. Так же нужно, чтоб сохранились ссылки там, где это нужно.
Изначально все было сделано примерно так
template <typename T, typename ...Args>
std::function<void()> createTask(T call, Args&& ... args)
{
return std::bind(call, std::forward<decltype(args)>(args)...);
}
Естественно, если у меня есть вот такой вот код:
void inc(int &test, int i)
{
test += i;
}
...
int test = 0;
auto t = createTask(inc, test, 1);
t();
std::cout << test << "\n";
то на выходе я получаю 0, ибо байнд теряет ссылку.
Выходом может стать std::ref, но оно не всегда очевидно.
Сделал вот такое вот решение.
template <typename T, typename ...Args>
std::function<void()> createTask(T call, Args&& ... args)
{
return [call, &args...]() { call(std::forward<decltype(args)>(args)...); };
}
и оно, кажется, работает. А вопрос в том на сколько это корректный код вообще?
В стандарте 11 плюсов нашел вот такое
A capture followed by an ellipsis is a pack expansion (14.5.3). [Example:
template<class... Args>
void f(Args... args) {
auto lm = [&, args...] { return g(args...); };
lm();
}
— end example]
но можно ли захватить Args&& ... args по ссылке? И куда эта «ссылка» будет?
cast eao197