33369


関数をクラスのコンストラクタで受け取り，そのクラスのメンバ関数に格納して，  
そのクラスの好きな位置で呼び出すことができるようにしたいのですが，

以下のようなクラスを作ってみたところ，メンバ関数funcに  
代入できませんでした．なにか解決策はありますでしょうか．

[code]

    #include <iostream>
    #include <functional>
    #include <thread>
    
    
    class myThread
    {
    public:
        //与えられた関数を格納する関数ポインタ
        template <class callable, class... arguments>
        std::function<callable(arguments...)> (*func)(); // ＜ーーここの宣言の仕方が良くないのだと思うのだけれど．．．
    
        //コンストラクタ．引数として，関数と任意長の引数を得る
        template <class callable, class... arguments>
        myThread(callable&& f, arguments&&... args)
        {
            std::function<typename std::result_of<callable(arguments...)>::type()> task(std::bind(std::forward<callable>(f), std::forward<arguments>(args)...));
            this->func = task; // ＜ーーここで代入できない
        }
    
        //引数で与えられた関数を元にループを作る
        void makeLoop()
        {
            while(true){
                this->func();
            }
        }
    
        //スレッドにて非同期実行を行う
        void run()
        {
            std::thread th(&myThread::makeLoop, this);
        }
    };
    
    //テスト用関数.引数を出力するだけ
    void test(int arg)
    {
        std::cout << arg << std::endl;
        return;
    }
    
    int main()
    {
        myThread thread1(test, "hello");
    
        return 0;
    }
    
[/code]

よろしくお願いします．


CC BY-SA 3.0
2017-03-16T11:43:48.007
33368
2017-03-16T12:14:54.343
21084
question
c++ c++11
c++で引数で与えられた関数をメンバ関数に格納するには


関数オブジェクト型(`std::function<void()>`)のメンバ変数として保持するのが簡単かと思います。

[code]

    class myThread {
        std::function<void()> func;
    public:
        template <class F, class ...Args>
        myThread(F&& f, Args&& ...args)
        {
            this->func = std::bind(std::forward<F>(f), std::forward<Args>(args)...);
        }
    
        //...
    };
    
[/code]

* * *

質問趣旨からそれますが、下記`run()`メンバ関数は期待通り動作しません。`std::thread`型変数に対して`join()`/`detach()`いずれも呼び出さないため、同オブジェクト破棄時つまり`run()`メンバ関数を抜けるときにプログラム異常終了します。詳細は[cpprefjp](https://cpprefjp.github.io/reference/thread/thread.html)サイトの説明を参照くさだい。

[code]

    void run()
    {
        std::thread th(&myThread::makeLoop, this);
    }
    
[/code]

クラス`myThread`が「なんらかの処理を行うスレッド」自身を表すのであれば、`std::thread`型メンバ変数として保持しておき、適切に`join()`/`detach()`を呼び出す必要があります。


CC BY-SA 3.0
2017-03-16T12:08:43.427
33369
2017-03-16T12:14:54.343
2017-03-16T12:14:54.343
49
49
33368
answer