Dato il seguente:Posso scrivere un functor C++ che accetta sia un puntatore raw sia un puntatore intelligente?
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;
}
};
Ho un contenitore di Foo*
e io uso std::find_if
e std::not1
per scoprire se ci sono elementi nel contenitore dove bar()
ritorna qualcosa di diverso da un dato valore. Il codice simile a questo:
// 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();
}
Avanti veloce verso il futuro ed ora ho un contenitore diverso, questa volta contenente std::tr1::shared_ptr<Foo>
. Mi piacerebbe semplicemente riutilizzare il mio functor in una versione sovraccaricata di isAllEqual()
. Ma non posso. Foo*
e shared_ptr<Foo>
sono diversi tipi. E ho bisogno di ereditare da unary_function
così posso usare not1
. Sarebbe più elegante se potessi evitare di scrivere lo stesso funtore due volte.
Domande:
- C'è un modo di scrivere
IsEqual
quindi è possibile utilizzare sia i puntatori prime e intelligente? - Mi sono ammanettato utilizzando
std::not1
? Dovrei semplicemente scrivereIsNotEqual
?
Restrizioni:
- non posso usare qualsiasi cosa dalla libreria spinta.
- Il nostro compilatore non è abbastanza bello da supportare C++ 0x lambda.
Questo suona come un esempio in cui i modelli sarebbero belli. – GWW
@Kristo: Il tuo compilatore è abbastanza interessante da fornire altri contenuti in C++ 0x, come 'std :: begin'? –
@ Ben, stiamo usando gcc 4.1.2, quindi probabilmente no. 'std :: begin' e' std :: end' dovrebbero essere banali da scrivere però. –