Вызов функции внутри лямбды, переданной в поток

Я пытаюсь создать объект, которому можно дать функцию и ее параметры своему конструктору. Затем этот класс будет вызывать данную функцию внутри лямбды, которая вместо этого передается потоку. Нечто подобное

class worker {
public:
    template <class Fn, class... Args>
    explicit worker(Fn f, Args ... args) {
        t = std::thread([&]() -> void {
                f(args...);
        });
    }
private:
    std::thread t;
};

int main() {
    worker t([]() -> void {
        for (size_t i = 0; i < 100; i++)
            std::cout << i << std::endl;
    });

    return 0;
}

Но я получаю следующую ошибку

error: parameter packs not expanded with '...': f(args...);

Что я здесь не так делаю? Любая помощь будет оценена.

1 ответ

Решение

Как сказано в комментариях, это прекрасно скомпилируется с gcc-4.9 (и выше), но если вам нужно использовать gcc-4.8, вы можете добавить параметры к лямбде в worker конструктор и передать аргументы через std::thread конструктор:

class worker {
public:
    template <class Fn, class... Args>
    explicit worker(Fn f, Args ...args) {
        t = std::thread([f](Args ...largs) -> void {
                f(largs...);
        }, std::move(args)...);
    }
private:
    std::thread t;
};

Это также создаст копию аргументов в лямбда-аргументах, в отличие от захвата по ссылке, которую вы использовали [&] это, вероятно, было неправильно в этом случае (см. комментарий @Yakk).

Другие вопросы по тегам