2016-10-10 59 views
1

集或地图排序谓语必须有一个简单的答案,这...如何适应平凡的指针

我有一个std ::设置或一个std ::地图或具有自然一些对象类型订购 - 说std :: less。

我需要改变我的集合或映射到包含代替T.

副本的shared_ptr

所以,我想是这样的:

using my_set std::set<std::shared_ptr<T>, std::less<*T>>; 

但我画一个空白为如何指定“在T的____适配器上使用较少的适配器,以便它在解除引用的成员上,而不是在shared_ptrs上!”

是否有std::less<std::dereference<std::shared_ptr<T>>>等价物?

+1

写一个自定义比较器? – NathanOliver

+0

绝对可以做到这一点。我的问题是:是不是有一个标准的适配器?它必须达到一吨! – Mordachai

+0

不确定,因为比较函数必须采用指针类型为“T”。类似'std :: less >>'会期望'T'。 – NathanOliver

回答

1

目前在C++标准库中没有函子来实现你想要的。你可以写一个自定义比较器,或者如果你经常需要这个功能,可以拿出一个函数对象。

相关和可能有帮助的线程;第一个提供了众多运营商的通用解决方案(即使这需要一点点的代码):

+0

谢谢。这些看起来很有希望帮助理解这个问题,以及为什么C++的这个角落仍然是一个主要的PIA。 – Mordachai

1

虽然标准库可能尚未提供你需要什么,我认为写你自己的是非常简单的std::dereference_less

#include <memory> 
#include <set> 

namespace std 
{ 
    template<typename T> 
    struct dereference_less 
    { 
     constexpr bool operator()(const T& _lhs, const T& _rhs) const 
     { 
      return *_lhs < *_rhs; 
     } 
    }; 
} 

int main() 
{ 
    using key_type = std::shared_ptr<int>; 
    std::set<key_type, std::dereference_less<key_type>> mySet; 
} 

Demo(重构了一下,在你的问题的模板类型别名等)

0

既然你已经改变你的内部接口的东西,需要提领你也可以只写一个包装类,并提供一个bool operator<()如下:

#include <memory> // shared_ptr 
#include <set>  // set 
#include <iostream> // cout 
using namespace std; 

template<typename T> 
class wrapper 
{ 
public: 
    shared_ptr<T> sp; 

    bool operator< (const wrapper<T>& rhs) const 
    { 
    return *(sp.get()) < *(rhs.sp.get()) ; 
    } 
    wrapper(){} 
    wrapper(shared_ptr<T> sp):sp(sp){} 
}; 

int main() 
{ 
    shared_ptr<int> sp1 (new int); 
    *sp1 = 1; 
    shared_ptr<int> sp2 (new int); 
    *sp2 = 2; 

    set<wrapper<int>> S; 
    S.insert(wrapper<int>(sp2)); 
    S.insert(wrapper<int>(sp1)); 

    for (auto& j : S) 
    cout << *(j.sp) << endl; 

    return 0; 
} 
+0

有趣的做法。感谢这个想法。 – Mordachai