別のスレッドでクラスを実行し、メインスレッドから制御 (一時停止、再開、停止など) できるクラスランナー (固定時間でクラスを実行する) を作成しようとしています。
そこで、C++11 の Functor などの機能を活用したいと考えています。しかし、奇妙な問題があります。ランナーに渡されたファンクターのデストラクタが 2 回呼び出されています。
#include <iostream>
#include <chrono>
#include <thread>
using namespace std;
class Runner {
public:
typedef function<bool()> fn_t;
Runner(fn_t &&fn) : fn_(move(fn)), thread_(Thread, ref(*this)) {
cout << "Runner" << endl;
}
~Runner() {
cout << "~Runner" << endl;
thread_.join();
}
private:
fn_t fn_;
thread thread_;
static void Thread(Runner &runner) {
while (runner.fn_()) {
cout << "Running" << endl;
this_thread::sleep_for(chrono::milliumseconds(1));
}
}
};
class Fn {
public:
Fn() : count(0) {
cout << "Fn" << endl;
}
~Fn() {
cout << "~Fn" << endl;
}
bool operator()() {
return (++count < 5);
}
private:
int count;
};
int main (int argc, char const* argv[])
{
Fn fn;
Runner runner(move(fn));
return 0;
}
出力:
Fn
Runner
~Fn
~Runner
Running
Running
Running
Running
Running
~Fn
~Fn
もし私が変われば
Fn fn;
Runner runner(move(fn));
に
Runner runner(Fn());
プログラムは何も出力せず、失速します。コンパイルの最適化を無効にしようとしましたが、何も変わりません。説明はありますか?
どうすればこれを修正できますか、または他の方法で同じことを行うことができますか? このクラスを std::async / std::thread のように実装する必要がありますか?
に更新 Runner runner(Fn())
このステートメントは、関数宣言として中断されました。
Runner runner((Fn()))
問題を解決しました。
すべてのコメントと回答に感謝します。rvalueを調べたところ、グラウンド 0 からの右辺値参照の意味を誤解しているようです。他の方法を試してみます。
この問題の最終的な解決策
#include <iostream>
#include <chrono>
#include <thread>
#include <vector>
using namespace std;
template<typename T, typename... Args>
class Runner {
public:
Runner(Args&&... args) :
t(forward<Args>(args)...),
thread_(Thread, ref(*this)) {
cout << "Runner" << endl;
}
~Runner() {
cout << "~Runner" << endl;
thread_.join();
}
private:
T t;
thread thread_;
static void Thread(Runner &runner) {
while (runner.t()) {
cout << "Running" << endl;
this_thread::sleep_for(chrono::milliseconds(100));
}
}
};
class Fn {
public:
Fn() : count(0) {
cout << "Fn" << endl;
}
~Fn() {
cout << "~Fn" << endl;
}
bool operator()() {
return (count++ < 5);
}
private:
int count;
};
int main (int argc, char const* argv[])
{
//vector<Fn> fns;
//fns.emplace_back(Fn());
Runner<Fn> runner;
return 0;
}
出力:
Fn
Runner
~Runner
Running
Running
Running
Running
Running
~Fn