2016-06-20 12 views
4

私はboost :: shared_ptrのセットを持っています。これは、共有ポインタによってではなく、文字列によって一意となります。私は共有ポインタを取得し、内容を比較する新しい比較関数を提供する必要がありますか、私は使用できるようなコンパレータが既に存在するのですか?std boost :: shared_ptrのセット<string>

答えて

5

これは非常に特殊なので、おそらくカスタムコンパレータが必要です。

これは動作するはずです:

struct pointercompare 
{ 
    bool operator()(const boost::shared_ptr<std::string>& a, const boost::shared_ptr<std::string>& b) 
    { 
     return (*a)>(*b); 
    } 
} 
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))); 

} 
を完全なライブラリを紹介
関連する問題