Могу ли я написать функтор 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 * , и я использую std :: find_if и std :: not1 , чтобы узнать, есть ли в контейнере какие-либо элементы, где bar () возвращает что-то отличное от заданного значения. код выглядит так:

// 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();
}

Перенесемся в будущее, и теперь у меня есть другой контейнер, на этот раз содержащий std :: tr1 :: shared_ptr . Я бы хотел просто повторно использовать мой функтор в перегруженной версии isAllEqual () . Но я не могу. Foo * и shared_ptr относятся к разным типам. И мне нужно чтобы унаследовать от unary_function , чтобы я мог использовать not1 . Это ' Было бы более элегантно, если бы я мог избежать написания одного и того же функтора дважды.

Вопросы:

  • Есть ли способ написать IsEqual , чтобы он мог использовать как исходные, так и интеллектуальные указатели?
  • Я сделал это надеть на себя наручники, используя std :: not1 ? Должен ли я просто написать вместо этого IsNotEqual ?

Ограничения:

  1. Я не могу использовать ничего из библиотеки boost.
  2. Наш компилятор недостаточно крут, чтобы поддерживать лямбда-выражения C ++ 0x.
8
задан Michael Kristofik 13 December 2010 в 20:25
поделиться