2016-05-12 13 views
9

has_equal_operatorをC++ 11で実装しようとしていますが、これまでの解決方法がありました。 intまたはstruct A{}のような単純なケースでは機能しますが、std::vector<A>の場合は失敗します(偽陽性を返します)。なぜそれが失敗し、これを修正する方法ですか?C++ 11でhas_equal_operatorの実装

#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; 
} 

出力:

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

どういう意味ですか、それは偽陽性ですか? '=='は2つのベクトルに対しては機能しませんか? – immibis

+1

@immibis 'std :: vector'の' operator == 'は、要素型に対して定義されている場合にのみ定義してください。 – o11c

+1

これは、 'bool operator ==(const vector <_Tp、_Allocator>&__x、const vector <_Tp、_Allocator>&__y)'が 'declurb <_Tp>の有効性に依存しないという事実と関係していると思います()==宣言<_Tp>() '。 – o11c

答えて

3

なぜそれが失敗していますか?

std::vector<A>は、あなたのコード内のstd::declval<T>() == std::declval<T>()==の一致である非会員operator==関数テンプレートを、持っています。チェックが成功します。

その関数テンプレートの本体がコンパイルされないという事実は、SFINAEとは無関係です。重要なことは宣言が有効であることです。

これを修正するにはどうすればよいですか?

私が考えることができる唯一の方法は、手動で標準的な容器の特性を特化することです。

+0

演算子==が非メンバー演算子であるという事実はなぜ問題なのですか? –