2017-05-16 6 views
2

値の型がペアであるイテレータに対して特殊なテンプレート関数を記述したいと思います。私はこれがstd :: mapのイテレータと一致するはずです。ペアを検出するためにイテレータの値の型がペアであるかどうかを確認するenable_if

template <typename> 
struct is_pair : std::false_type 
{ }; 

template <typename T, typename U> 
struct is_pair<std::pair<T, U>> : std::true_type 
{ }; 

// also tried this, but it didn't help 
template <typename T, typename U> 
struct is_pair<std::pair<const T, U>> : std::true_type 
{ }; 

それから私は、関数の宣言にenable_if使用:

template<class ITR> 
decltype(auto) do_stuff(
     std::enable_if<is_pair<typename ITR::value_type>::value, ITR> itr) { 
    //access of itr->second ok. 
} 

私はマップイテレータで、この機能を使用する場合しかし、私は次のエラーを取得しますclang(Xcode 8.3)のメッセージ:

候補テンプレートが無視されました: 'enable_if'と '__map_iterat'が一致しませんでしたまたは '

これ以上の理由はありません。

__map_iteratorのタイプを調べると、is_pair checkと一致するように見えます。

+0

私は*(DEREF後)マップイテレータがペアに*参照*だけでなく、値型であると思います*。このフライを作るためにリファレンスを取り除かなければならないことは間違いないでしょう。 – WhozCraig

答えて

1

Iは、本質的にそれがあった、それを考え出した:SFINAE working in return type but not as template parameter

だから最終的に、私はこの署名を使用した:iがマップ内の値への実際の参照を必要とするので

template<class ITR> 
typename std::enable_if_t<is_pair<typename ITR::value_type>::value, ITR>::value_type::second_type& get_value_from_iterator(ITR itr) 

参照が必要とされました。

チェックのconstバージョンは必要ありませんでした。

3

ので、同じようには、別のデフォルトのテンプレート引数にstd::enable_ifを移動すると良いでしょう:ITR && itrは今普遍的な参照であるため、

template<class ITR, typename = typename std::enable_if<is_pair<typename ITR::value_type>::value, ITR>::type> 
decltype(auto) do_stuff(ITR && itr) { 
    //access of itr->second ok. 
} 

これは、引数控除をブロックしません。

全例:

#include <type_traits> 
#include <utility> 
#include <map> 

template <typename> 
struct is_pair : std::false_type 
{ }; 

template <typename T, typename U> 
struct is_pair<std::pair<T, U>> : std::true_type 
{ }; 


template<class ITR, typename = typename std::enable_if<is_pair<typename ITR::value_type>::value, ITR>::type> 
decltype(auto) do_stuff(ITR && itr) { 
    //access of itr->second ok. 
} 

int main() 
{ 
    std::map<int, int> foo{ 
     { 1, 2 }, 
     { 3, 4 }, 
    }; 

    do_stuff(foo.begin()); 
    return 0; 
} 

Live on gcc.godbolt.org

関連する問題