2016-07-27 2 views
1

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

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...); 

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

+5

Какой компилятор? Не связанный с вашей ошибкой компилятора, но вы должны знать, что написанный код почти наверняка приведет к неопределенному поведению, поскольку lambda захватывает по ссылке, перемещается в поток, тогда область, в которой данные действительны, остается. – Yakk

+3

Похоже, у вас слишком много брекетов. – TartanLlama

+2

Ваш код не компилируется, как есть, там скобки везде, 't' не объявлен, ... После очистки у меня нет проблем с компиляцией этого, поэтому вы должны предоставить [MCVE] (http://stackoverflow.com/помощь/mcve). – Holt

ответ

2

Как сказано в комментариях, это компилироваться с 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 комментарий).

+0

Спасибо, это сработало! – Aram

+0

Просто пример игрушек, который я знаю, но не присоединяясь или не отсоединяя эту нить, ваш основной будет делать неожиданный вызов 'terminate()' ... –