2016-11-05 6 views
0

this questionを解決しようとしています。C++ 17、SFINAEでオートノンタイプテンプレートパラメータが動作しないのはなぜですか

以下のコードでは、FunctionInfoを使用して、パラメータリストで選択された関数のオーバーロードを検出したいと考えています。

付:

decltype(MethodInfo<Foo, int>::get(&Foo::foo)) 

私は、パラメータリストに基づいて、適切なオーバーロード機能を選択することができます。

は私が使用できるように1歩に行きたい:

error: non-type template parameter 'f' with type 'auto' has incompatible 
    initializer of type '<overloaded function type>' 
FunctionInfo<Foo, std::tuple<int>, &Foo::foo>::type 
            ^~~~~~~~~ 

マイ:

FunctionInfo<Foo, std::tuple<int>, &Foo::foo>::type 

をしかし、私は頭の中で、以下のソリューション、打ち鳴らす4.0.0レポートこれにしようとしたとき問題はSFINAEがどの機能が適切かを選択することに関係しない理由です。

#include <type_traits> 
#include <tuple> 

template<typename T, typename... Args> 
struct MethodInfo { 
    template<typename Ret> 
    static auto get(Ret(T::*)(Args...)) -> Ret(T::*)(Args...); 
}; 

template<typename T, typename Tuple> 
struct MethodInfoFromTuple; 

template<typename T, typename...Args> 
struct MethodInfoFromTuple<T, std::tuple<Args...>>{ 
    using type = MethodInfo<T, Args...>; 
}; 

template<typename T, typename ArgPack, auto f, 
      typename Func = decltype(MethodInfoFromTuple<T, ArgPack>::type::get(f))> 
struct FunctionInfo { 
    using type = Func; 
}; 

struct Foo { 
    int foo(int); 
    // Uncomment this line then only first static_assert work 
    // int foo(int, int); 
}; 

int main() { 
    static_assert(std::is_same< 
         int(Foo::*)(int), 
         decltype(MethodInfo<Foo, int>::get(&Foo::foo)) 
          >::value, ""); 
    static_assert(std::is_same< 
         int (Foo::*)(int), 
         FunctionInfo<Foo, std::tuple<int>, &Foo::foo>::type 
          >::value, ""); 

} 

答えて

1

オーバーロードセットはC++の値ではありません。テンプレートの非型引数は値です。

オーバーロードセットは、特定のルールを使用して、狭い一連の状況で値に解決されます。これらのルールは、「それぞれの可能性を試してはいけません。代わりに、正確なマッチが選択されるケースと、実行可能なオーバーロードのオーダーが実行され、ネクタイがない場合、「ベスト」が選択されるケースがあります。

autoに渡す場合もありません。

+0

「実行可能なオーバーロードの注文が行われている場合と、タイがない場合」のどちらのケースですか? – Danh

+0

@danhそれを呼び出すと、どの過負荷が選択されます。一致する関数/メソッドのポインタに渡すと、完全一致が実行されます。 – Yakk

+0

これは、テンプレートパラメータの 'auto'に対して正確なマッチングが行われていること、過負荷がないこと、またはSFINAEを使って過負荷を選択することを意味しますか? – Danh

関連する問題