は、次のことを考える:生ポインタとスマートポインタの両方を受け付けるC++ファンクタを書くことはできますか?
struct Foo
{
int bar() const;
};
struct IsEqual : public std::unary_function<Foo*, bool>
{
int val;
IsEqual(int v) : val(v) {}
bool operator()(const Foo* elem) const
{
return elem->bar() == val;
}
};
私はFoo*
のコンテナを持っていると私はbar()
が与えられた値と異なる何かを返すコンテナ内のすべての要素があるかどうかを確認するためにstd::find_if
とstd::not1
を使用しています。今回はstd::tr1::shared_ptr<Foo>
を含む、将来へ
// Are all elements equal to '2'?
bool isAllEqual(const std::vector<Foo*> &vec)
{
return find_if(vec.begin(), vec.end(), std::not1(IsEqual(2))) == vec.end();
}
早送りと私は今、別のコンテナを持っています。コードは次のようになります。 isAllEqual()
のオーバーロードされたバージョンで、私のファンクターを単に再利用したいのです。しかし、私はできません。 Foo*
とshared_ptr<Foo>
は異なるタイプです。そしてunary_function
から継承する必要がありますので、not1
を使用できます。同じファンクタを2回書くのをやめれば、よりエレガントになります。
質問:
- が、それは生とスマートポインタの両方を使用できるように
IsEqual
を書くためにどのような方法がありますか? std::not1
を使用して手錠をかけましたか?代わりにIsNotEqual
と書いてください。
制限:
- 私はブーストライブラリーから何かを使用することはできません。
- 私たちのコンパイラは、C++ 0x lambdasをサポートするのに十分ではありません。あなたは
->
とdereferencableすべてなので、生のポインタとスマートポインタに異なるoperator()
のインスタンスを持っていますtemplate<typename PtrToFoo> struct IsEqual : public std::unary_function<PtrToFoo, bool> { int val; IsEqual(int v) : val(v) {} bool operator()(PtrToFoo elem) const { return elem->bar() == val; } };
:
これは、テンプレートがすばらしいと思われる例のようです。 – GWW
@Kristo:あなたのコンパイラは 'std :: begin'のような他のC++ 0xのものを提供するのに十分ですか? –
@Ben、私たちはgcc 4.1.2を使用しています。 'std :: begin'と' std :: end'は書くべきではありません。 –