std set of boost :: shared_ptr <string>

时间:2016-06-20 09:09:42

标签: c++ boost shared-ptr

我有一组boost :: shared_ptr,我希望不是通过共享指针而是通过字符串来排序和统一。我是否必须提供一个新的比较函数来获取共享指针并比较内容,或者我是否可以使用这样的比较器?

2 个答案:

答案 0 :(得分:5)

这非常具体,所以你可能需要一个自定义比较器。

这应该有效:

struct pointercompare
{
    bool operator()(const boost::shared_ptr<std::string>& a, const boost::shared_ptr<std::string>& b)
    {
        return (*a)>(*b);
    }
}

答案 1 :(得分:1)

我会写一个包含谓词和迭代器的通用方法,它将值语义映射到任何类似指针的所有者。

然后变得完全通用且可重复使用。

简单版本

以下红利代码为此类内容介绍了一个完整的库

#include <utility>
#include <boost/shared_ptr.hpp>
#include <vector>
#include <algorithm>

template<class Comp> 
struct pointee
{
  pointee(Comp comp = Comp()) : _comp(comp) {}

  template<class APtr, class BPtr>
    bool operator()(const APtr& a, const BPtr& b)
    {
        return _comp(*a, *b);
    }

  Comp _comp;
};



int main()
{
  std::vector<boost::shared_ptr<int>> v;

  std::sort(v.begin(), v.end(), pointee<std::less<>>());
  std::sort(v.begin(), v.end(), pointee<std::greater<>>());

}

奖励积分......

#include <utility>
#include <boost/shared_ptr.hpp>
#include <vector>
#include <algorithm>
#include <functional>


template<class T, class X, class Y>
struct is_binary_op
{
    template<class U> static auto test(U* p) -> decltype((*p)(std::declval<X>(), std::declval<Y>()), void(), std::true_type());
    template<class U> static auto test(...) -> decltype(std::false_type());

    static constexpr bool value = decltype(test((T*)0))::value;
};

template<class T, class X, class Y> static constexpr bool IsBinaryOp = is_binary_op<T, X, Y>::value;

template<class T, class X>
struct is_unary_op
{
    template<class U> static auto test(U* p) -> decltype((*p)(std::declval<X>()), void(), std::true_type());
    template<class U> static auto test(...) -> decltype(std::false_type());

    static constexpr bool value = decltype(test((T*)0))::value;
};
template<class T, class X> static constexpr bool IsUnaryOp = is_unary_op<T, X>::value;

namespace detail {
    template<class Comp>
    struct pointee
    {
        pointee(Comp comp = Comp()) : _comp(comp) {}

        template<
        class APtr,
        class BPtr
        >
        auto operator()(const APtr& a, const BPtr& b) const
        -> std::enable_if_t<
        IsBinaryOp<Comp, decltype(*a), decltype(*b)>
        , bool>
        {
            return _comp(*a, *b);
        }

        template<
        class APtr
        >
        auto operator()(const APtr& a) const
        -> std::enable_if_t<
        IsUnaryOp<Comp, decltype(*a)>
        , bool>
        {
            return _comp(*a);
        }

        Comp _comp;
    };

    template<class Iter>
    struct deref_iter : Iter
    {
        deref_iter(Iter iter) : Iter(iter) {}

        auto& operator*() const {
            return **static_cast<const Iter&>(*this);
        }
    };
}

template<class Pred>
auto pointee(Pred&& pred)
{
    return detail::pointee<std::decay_t<Pred>>(std::forward<Pred>(pred));
}

template<class Iter>
auto deref_pointee(Iter&& iter)
{
    return detail::deref_iter<std::decay_t<Iter>>(std::forward<Iter>(iter));
}


int main()
{
    std::vector<boost::shared_ptr<int>> v;

    // sort using the less predicate on the pointee
    std::sort(v.begin(), v.end(), pointee(std::less<>()));

    // sort using the greater predicate on the pointee
    std::sort(v.begin(), v.end(), pointee(std::greater<>()));

    // apply a unary predicate to every pointee
    std::for_each(v.begin(), v.end(), pointee(std::logical_not<>()));

    // transform the pointees by binding a binary predicate to a value and
    // turning it into a unary predicate that adds 6
    std::transform(v.begin(), v.end(), 
                   deref_pointee(v.begin()), 
                   pointee(std::bind(std::plus<>(), 6, std::placeholders::_1)));

}