2016-05-12 22 views
9

Sto cercando di implementare has_equal_operator in C++ 11 e finora ho trovato la seguente soluzione. Funziona per casi semplici come int o struct A{} ma non riesce (restituendo il falso positivo) per std::vector<A>. Perché sta fallendo e come risolvere questo problema?implementazione di has_equal_operator in C++ 11

#include <vector> 
#include <iostream> 

template<typename T> 
constexpr auto has_equal_operator(int) -> decltype(std::declval<T>() == std::declval<T>(), bool()) { return true; } 
template<typename T> 
constexpr bool has_equal_operator(...) { return false; } 

struct A {}; 

void test() 
{ 
    std::cout << "has_equal_operator<int>: " << has_equal_operator<int>(0) << std::endl; 
    std::cout << "has_equal_operator<A>: " << has_equal_operator<A>(0) << std::endl; 
    std::cout << "has_equal_operator<std::vector<A>>: " << has_equal_operator< std::vector<A> >(0) << std::endl; 
} 

uscita:

has_equal_operator<int>: 1 
has_equal_operator<A>: 0 
has_equal_operator<std::vector<A>>: 1 
+2

Cosa intendi, è un falso positivo? '==' non funziona per due vettori per te? – immibis

+1

@immibis 'std :: vector''s' operator == 'deve essere definito solo se è definito per il tipo di elemento. – o11c

+1

Penso che questo potrebbe essere qualcosa a che fare con il fatto che 'bool operator == (const vector <_Tp, _Allocator> & __x, const vector <_Tp, _Allocator> & __y)' non dipende dalla validità di 'declval <_Tp>() == declval <_Tp>() '. – o11c

risposta

3

Perché si fallendo?

std::vector<A> ha una funzione di modello non membro operator==, che è una partita per la == in std::declval<T>() == std::declval<T>() nel codice. Quindi il controllo ha successo.

Il fatto che il corpo di tale modello di funzione non venga compilato è irrilevante per SFINAE; tutto ciò che conta è che la dichiarazione sia valida.

Come risolvere il problema?

L'unico modo che posso pensare è di specializzare manualmente la propria caratteristica per contenitori standard.

+0

Perché è un problema il fatto che l'operatore == sia un operatore non membro? –