2011-02-07 5 views
3

boost :: bindまたはboost :: lambdaを使用して変換-bool演算子をバインドするにはどうすればよいですか?boost :: bind/lambdaとoperator bool()

たとえば、クラスCを持ち、演算子bool()とlist<C>があるとします。 boolに変換するとfalseに評価されるすべての要素を削除するには、remove_ifとbind/lambdaを使用するにはどうすればよいですか?

答えて

5

これにはstd::bindまたはstd::remove_ifを使用する必要はありません。 std::removeは十分でしょう。

std::vector<T> v; // Assuming T provides some conversion to bool 

// Remove all elements that evaluate to 'false': 
v.erase(std::remove(v.begin(), v.end(), false), v.end()); 

それとも、あなたはstd::remove_ifstd::logical_not関数オブジェクトを使用することができます。

v.erase(std::remove_if(v.begin(), v.end(), std::logical_not<T>()), v.end()); 

をクラスが実際operator bool()過負荷を実装する必要があることは非常に稀である:原因Cで問題にする++このような変換を提供すると、間違って誤ったコードを書いて、変換が使用されることを期待しないところで変換を利用することが容易になります。実際のoperator bool()オーバーロードの代わりにセーフ・ブール・イディオムを実装するほうがはるかに優れています。これの欠点は、safe-boolイディオムが特定されていない型への変換に依存しているため、実際にはoperator bool()のオーバーロードにバインドできないことです。

+0

注 'remove'アプローチと' remove_if'アプローチの間に違いがあること: 'remove'アプローチは=演算子'の使用に依存しています= '明示的に等価でない型に対しては機能しません。例えば、 'remove'アプローチは' std :: function'オブジェクトの範囲では機能しませんが、 'operator! 'の使用だけに依存する' remove_if'アプローチはうまく動作します。 [私はこれをある時点で私の答えに編集します。] –

+0

ありがとう。あなたはこの場合remove_ifの代わりにremoveが最も簡単なアプローチであることは間違いありません。 logical_notを使用することもできます。もしTが何とか自動的にコンパイラによって自動的に導かれれば、それはより良いでしょう。 – imre

+1

@imre:この場合、テンプレート引数を必要としない独自の関数オブジェクトを書くのはかなり簡単です: 'struct awesome_not {template bool operator()(const T&x){return!x; }}; '[私は最終的に私の答えにそれを編集します。] –

0

演算子がfalseと評価された場合に削除する必要がある場合はstd :: logical_notを使用します。あなたが真の場合は削除する必要がある場合は、使用することができます。

remove_if(..., ..., bind(&C::operator bool, _1)); 
関連する問題