Ho una functor che opera su un contenitore di tipo U
di elementi di tipo T
questo modoC++ determinare se un contenitore ha :: find()
template<typename T, template<typename...> class U>
class asserter
{
public:
asserter(U<T> &c) : container(c) { };
void operator()(T lhs)
{
CU_ASSERT(container.find(lhs) != container.end());
};
private:
U<T> &container;
};
che posso usare come
std::set<std::string> a, c;
...
asserter<std::string, std::set> ass(c);
for_each(a.begin(), a.end(), ass);
Dove stiamo ignorando std::includes()
per il momento.
Questo funziona perfettamente se il contenitore è uno dove è definito U::find()
. Se non lo è, vorrei tornare a std::find()
. D'altra parte preferisco usare U::find()
su std::find()
se è disponibile.
In C++ 11 (o 17 se necessario) è possibile determinare se è disponibile U::find()
(possibilmente restrittivo per STL) per U e in tal caso utilizzarlo, altrimenti utilizzare std::find()
?
Una risposta più utile spiegherebbe anche perché il codice funziona. Per esempio, mi aspettavo una risposta che impiegasse SFINAE. La parte 'decltype (...)' una tecnica SFINAE in C++ 17 (penso che questa sintassi di espressione lambda sia C++ 17)? Inoltre, 'int' usato per forzare quella firma ad avere la preferenza sul sovraccarico' long'? –
Mi preoccupo che 'std :: find' sia per l'uguaglianza mentre' std :: set :: find' ecc è per equivalenza. Dobbiamo considerarlo? –
@NickyC So che * teoricamente * sono diversi, ma quanto spesso accade nel mondo reale? Penso che 'set' e' map' (ei loro cugini 'multi') siano gli unici in cui è importante,' unordered_set' e 'unordered_map' dovrebbero usare l'uguaglianza. –