std::bindではデフォルト引数を省略できない
std::bindを使っていたらある問題に遭遇した。
void func(int a){ std::cout << a * 10 << std::endl; } int main(){ using namespace std::placeholders; auto fuction = std::bind(func, _1); function(2); }
std::bind
を使ってライブラリで用意されている関数を束縛し別のところで呼び出す、といったことをしたかったのだが、これが何故かコンパイルが通らなかった。(実際は、クラスのメンバ関数をbindした。簡単のためそのコードはここに示す )
なぜだろうか……といろいろ調べて回ったところ、とても単純な話だった。
void func(int a, int b = 10){ std::cout << a * b << std::endl; } int main(){ using namespace std::placeholders; auto fuction = std::bind(func, _1); function(2); }
引数1つで呼び出すものと思っていたfunc()
関数が、実際は第2引数にintを取る関数で、それにデフォルト引数が設定されていた。じゃあどうやってこの関数を束縛すればいいかというと、bind時、デフォルト引数も明示的に渡せばよい。
// Error! // auto function = std::bind(func, _1); // OK! auto function = std::bind(func, _1, 10); // call function(2);
bindは使うべきではないという話
ここまでbind
を使って関数を束縛してきたが、調べてみると、bindはパフォーマンス上に問題があるらしい。
じゃあ代わりに何を使うのかっていうと、みんな大好きラムダ式である。
// Error! // auto function = std::bind(func, _1); // OK! (low performance) auto function = std::bind(func, _1, 10) // OK! (high performance) auto function = [=](int _1){ func(_1); }; // call function(2);
Compiler Explorer でbind
とラムダ式
を比較してみると一目瞭然でパフォーマンスにかなり影響することがわかる。
まとめ
bindなんか使わずラムダを使おう。