新しもの好きプログラマの耳より情報ブログ

仕事でもあるプログラミングについて役に立ちそうな情報を発信していこうというブログです。役に立たなそうな情報はfacebookで。

std::threadとラムダ式を使ってみたら、ネイティブC++がいつの間にかだいぶ便利になってることに今更気づいた

いまさら感があるが、std::threadの便利さに恐れ入ったので記事を書く。感覚的には、C#のSystem.Threading.Thread+ラムダ式と同じくらいの感じで高速に書けそう。使ってる人にとっては常識的な話なので、そういう人はスルーしてください。

ごく簡単な処理を別スレッドで実行するためにスレッドを立てたい。そのスレッドの管理は不要。というケースは割とある。

C#のTaskやらThreadやらを使ってラムダ式でスレッドを立てるのに慣れてしまうと、ネイティブC++(VC++)でこれを書くのが面倒で仕方ない。

C#ならラムダ式の変数のキャプチャがあるので、こんな感じで書いたとする。

var event = new 何かイベント();
Task.Run(()=>{

    event.WaitOne();
    何かアクション();
});

従来の(かなり古い?)VC++で書こうとすると、APIの選択はともかくだいたいこんな感じだろうか。

void threadFunc(void* pParam){
    auto pEvent = reinterpret_cast<何かイベント*>(pParam);
    Wait系処理(*pEvent);
    何かアクション();
    delete pEvent;
}

auto event = new 何かイベント();
_beginthread(threadFunc, 0, &event)

まず別の関数を書くのが面倒・・・だし、newしたポインタをvoid*で渡し、渡した先で正しい方にキャストしてdeleteされることを期待するというのも、どうにも怖い感じだ。

これをstd::threadで書くと、こうなる。

auto event = new 何かイベント();
std::thread th([event]{
    Wait系処理(event);
    何かアクション();
});
th.detach();

なんと、ほぼTaskと同じノリで書ける。ラムダ式と変数のキャプチャという機能はここまで強力だったか・・・。

5年くらい前にこういった面倒さからネイティブC++はできるだけ避けるようになっていて、昔のコードの保守をするときもすぐにC++/CLIを使って.NETのコードを呼ぶように書くのが常だった。

しかし、ここまで便利になっているのなら、ちょっとした処理はネイティブC++のままで書いてもぜんぜん問題なさそうだ。C++を見直してみようと思う。