2015-09-16 9 views
8

Ho una serie di shared_ptr e vorrei trovare un valore in esso:Trova un valore in un insieme di shared_ptr

typedef std::shared_ptr<int> IntPtr; 

struct Compare { 
    bool operator() (const IntPtr& a, const IntPtr& b) { 
    return *a < *b; 
    } 
}; 
std::set<IntPtr, Compare> s; 

auto x = std::make_shared<int>(3); 
s.insert(x); 

bool found = s.find(std::make_shared<int>(3)) != s.end(); 

Sta funzionando, ma non efficiente - ha bisogno di nuovo un puntatore temperatura ogni volta quando si cerca di trovare un valore.

Esiste un altro modo?

Sembra che Searching in a set of shared_ptr<QString> abbia alcune idee che potrebbero essere d'aiuto?

+0

_ "è necessario creare un nuovo puntatore temporaneo ogni volta che si tenta di trovare un valore." _ Che cosa significa? –

+0

È l'argomento di 's.find', lo' std :: make_shared (3) ' – Gombat

+2

C'è anche' std :: find_if', e alla fine potresti usare un set non ordinato? –

risposta

14

(In C++ 14) Fai la tua comparatore a transparent one e definire la logica aggiuntiva per confrontare memorizzati shared_ptr s con int s:

struct Compare 
{ 
    using is_transparent = void; 
    // ~~~~~~~~~~~~~^ 

    bool operator() (const IntPtr& a, const IntPtr& b) const 
    { 
     return *a < *b; 
    } 

    bool operator() (const IntPtr& a, int b) const 
    { 
     return *a < b; 
    } 

    bool operator() (int a, const IntPtr& b) const 
    { 
     return a < *b; 
    } 
}; 

DEMO

+1

Grazie, upvoted, ho imparato qualcosa di nuovo oggi. Cioè, ho letto di comparatori trasparenti, ma non è rimasto. Non l'ho associato a nessun caso pratico d'uso. –

0

Con un programma a thread singolo è possibile ridurre la spese generali a una singola allocazione globale:

using Int_ptr_set = std::set<IntPtr, Compare>; 

auto find(int const v, Int_ptr_set const& values) 
    -> bool 
{ 
    static IntPtr p = std::make_shared<int>(0); 
    *p = v; 
    return values.find(p) != values.end(); 
} 

Disclaimer: codice non toccato dalle mani del compilatore.

Per il threading si potrebbe considerare di rendere il suddetto un metodo di una classe, con p come membro, quindi creare una statica thread-local di quella classe.

Problemi correlati