Шаблонный компаратор как третий аргумент в find_if - PullRequest
0 голосов
/ 18 марта 2019

У меня есть программа, которая пытается найти слабый_вектор в векторе.Это работает совершенно нормально.Но, может быть, есть способ передать шаблонный компаратор в качестве третьего аргумента для find_if?Нечто похожее на TWeakComparator.Это значительно сократит код.Заранее спасибо.Вот мой код:

#include <iostream>
#include <vector>
#include <memory>

using namespace std;

class Car
{
};

template<class T>
struct TWeakComparator: private std::unary_function<Car, bool>
{
    explicit TWeakComparator(const T& ptr) : m_comparePtr(ptr) { }
    bool operator()(const T& ptr1) const
    {
        if (ptr1.expired() || m_comparePtr.expired())
            return false;

        return ptr1.lock() == m_comparePtr.lock();
    }
private:
    const T& m_comparePtr;
};

struct WeakComparator: private std::unary_function<Car, bool>
{
    explicit WeakComparator(const std::weak_ptr<Car>& ptr) : m_comparePtr(ptr) { }
    bool operator()(const std::weak_ptr<Car>& ptr1) const
    {
        if (ptr1.expired() || m_comparePtr.expired())
            return false;

        return ptr1.lock() == m_comparePtr.lock();
    }
private:
    const std::weak_ptr<Car>& m_comparePtr;
};

int main()
{
    std::vector<std::weak_ptr<Car>> cars;

    std::shared_ptr<Car> lambo = std::make_shared<Car>();
    std::weak_ptr<Car> wPtr(lambo);
    cars.emplace_back(lambo);

    const auto pos = std::find_if(cars.begin(), cars.end(), WeakComparator(wPtr));

    if (pos == cars.end())
        std::cout << "Not found!" << std::endl;
    else
        std::cout << "Found!" << std::endl;

    return 0;
}

1 Ответ

0 голосов
/ 18 марта 2019

Сделать WeakComparator шаблоном класса.

template <typename T>
struct WeakComparator : private std::unary_function<T, bool>
{
   explicit WeakComparator(const std::weak_ptr<T>& ptr) : m_comparePtr(ptr) { }
   bool operator()(const std::weak_ptr<T>& ptr1) const
   {
      if (ptr1.expired() || m_comparePtr.expired())
         return false;

      return ptr1.lock() == m_comparePtr.lock();
   }
   private:
   const std::weak_ptr<T>& m_comparePtr;
};

и затем используйте

const auto pos = std::find_if(cars.begin(), cars.end(), WeakComparator<T>(wPtr));

Если вы можете использовать C ++ 17, вы можете пропустить часть <T> и использовать

const auto pos = std::find_if(cars.begin(), cars.end(), WeakComparator(wPtr));

В противном случае вы можете использовать вспомогательную функцию для уменьшения избыточности:

template <typename T>
WeakComparator<T> makeWeakComparator(const std::weak_ptr<T>& ptr)
{
   return WeakComparator<T>(ptr);
}

и используйте

const auto pos = std::find_if(cars.begin(), cars.end(), makeWeakComparator(wPtr));
...