2016-10-10 55 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