2016-07-27 9 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

コンパイラは何ですか?コンパイラのエラーとは無関係ですが、ラムダの参照がスレッドに移動され、データが有効なスコープが残されているため、記述されたコードがほぼ確実に未定義の動作になることに注意してください。 – Yakk

+3

あなたはあまりにも多くの括弧を持っているように見えます。 – TartanLlama

+2

あなたのコードはそのままではコンパイルされません、どこでもかっこがあり、 't'は宣言されていません...クリーニング後、私は問題をコンパイルするので、[MCVE](http://stackoverflow.com)を提供してください。/help/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()'を予期せずに呼び出します。 –

関連する問題