私は関数の戻り値の型を取得するためにstd :: result_ofを使用して関数呼び出しラッパーを作成するためにSFINAEを使用しようとしています。問題を再現するために、少量のサンプル:std :: result_of voidの戻り値の型に失敗しました
GCC 4.9.2の結果でこれをコンパイルvoid test(int) {}
template<typename T, typename... Args, typename R = typename std::result_of<T(Args...)>::type, typename std::enable_if<!std::is_void<R>::value, int>::type* = nullptr>
int test2(R& ret_param, Args... args)
{
T* test_call = test;
ret_param = test_call(args...);
return 0;
}
template<typename T, typename... Args, typename std::enable_if<std::is_void<typename std::result_of<T(Args...)>::type>::value, int>::type* = nullptr>
int test2(Args... args)
{
T* test_call = test;
test_call(args...);
return 0;
}
int main()
{
test2<decltype(test)>(1);
}
に:問題は、何らかの形で「型名のstd :: result_of ::タイプは」と評価されていることである
68:26: error: no matching function for call to 'test2(int)'
68:26: note: candidates are:
46:5: note: int test2(R&, Args ...) [with T = void(int); Args = {}; R = int; typename std::enable_if<(! std::is_void<R>::value), int>::type* <anonymous> = 0u]
46:5: note: no known conversion for argument 1 from 'int' to 'int&'
56:5: note: template<class T, class ... Args, typename std::enable_if<std::is_void<typename std::result_of<_Functor(_ArgTypes ...)>::type>::value, int>::type* <anonymous> > int test2(Args ...)
56:5: note: template argument deduction/substitution failed:
55:142: error: function returning a function
55:142: note: invalid template non-type parameter
関数は関数を返す? SFINAEを使用して、テンプレート関数の戻り値の型が無効な場合に、異なる関数を選択するように強制するための正しい方法は何ですか?テスト関数がintを返す逆の場合に言及する価値があります。さらに、enable_ifがstd :: is_voidの解決のために削除された場合、この場合は動作します(ただし、戻り値の型がある場合は両方の関数が有効な解像度になり、戻り値を期待しない場合はコンパイルが失敗します) )。
まず、 'decltype(test)'は関数型です。これを 'T'に束縛しています。これは、有効化ロジックで戻り型として扱われます。 –
私は 'typename'の代わりに' class'を使うでしょう。私はそれらの複数の100文字の行を避けるでしょう。読書できるように物事を自然に分割してみてください。 –
私が理解しているのは、std :: result_of :: typeは、引数Argsで呼び出された場合の関数Tの戻り値の型です。これは、私が有効化ロジックで使用しているものです。 –
Grahalt