なぜC++ 11では以下のコンパイルが行われますか? (私はそれがリンクされないことを知っています)1()
は関数型ではないので、私はstd::enable_if
テストが失敗すると期待しています。std :: enable_if引数は関数ですか?
答えて
#include <type_traits>
template <typename Func, typename... Args>
typename std::enable_if<std::is_function<Func(Args...)>::value>::type
delegate(Func, Args...);
int main(void) {
delegate(1); // << Why does this line compile?
return 0;
}
Func
Args
が空であるので、Func(Args...)
がint()
である、すなわち、 "int
を返す()
の機能"、int
あります。
is_function
がtrueを返すものは、値渡しの関数パラメータの型にはなりません。何をしたいのかは分かりません。
私は
Func
は、そのためのArgs...
使用式SFINAEに適用することができ 機能(好ましくは関数ポインタ)であるとき、呼び出し可能のみにデリゲートを取得しようとしていました。
template <typename Func, typename... Args>
auto delegate(Func f, Args... args) -> decltype(f(args...), void());
あなたが実際に何をしたいのかに応じて、std::move
f
とargs
にしたいことがあります。
小さなコメント - 私はOPがデリゲートから関数の戻り値を返すことを望んでいると思います。だからおそらく 'decltype(f(args ...)); '(もちろん、私のところは純粋な推測です)。 – SergeyA
私は実際に 'delegate'が' void'を返すようにしたいと思います。上記は素晴らしいですが、感謝します。 :)好奇心から、それはなぜ 'void()'ですか? – oconnor0
単に 'decltype'が型を分解するためにオブジェクトを必要とするからです。 'void()'はvoid型のオブジェクトとして機能します。しかし、好奇心のために、なぜsfinaeが欲しいのですか?下の私の答えに示されているような単純な関数の何が間違っていますか? – SergeyA
あなたが書いたコードは、常にtrueになります。あなたがすべてでenable_if
を必要としないようではない、それは確からしいけどおそらくstd::is_function<Func>...
を意味し、私は間違っているとenable_if
がキーである場合は、しかし、単純な
template <class R, class... ARGS>
R delegate2(R (*fun)(ARGS...), ARGS...);
とのより良いいただきたいですこのコメントに基づいて
#include <type_traits>
template <typename Func, typename... Args>
typename std::enable_if<std::is_function<std::remove_pointer_t<Func>>::value>::type
delegate(Func, Args...);
void check(int);
int main(void) {
delegate(check, 10); // << good line compiles
delegate(10); // << this bad line does not
return 0;
}
@ T.C。、私の更新された答えを見てください - それは適切なチェックコールで動作します。 – SergeyA
@ T.C。、私はずっと前になぜ尋ねるのをやめました。とにかく、コードをより良いものに更新しました。 – SergeyA
この最初の試みは、 'delegate2'のようなものでした。残念なことに、型が正確に一致する必要があります。つまり、 'fun'が' long'をとる場合、 'int'(リテラルなど)は渡せませんが、明示的にキャストする必要があります。コンバージョンを行うか、そうでなければ型の一致を助けるための代理コールを探していたいと思っていました。 – oconnor0
:あなたのケースの成功に、ここにあなたがこれを行うことができる方法である
が間違った型特性を使用している
Args...
に適用できる関数(好ましくは関数ポインタ)であるとき
は、私は、デリゲートが唯一の呼び出し可能であることを取得しようとしていました。 Func
がArgs...
で呼び出し可能かどうかをチェックするには、これらの引数を使用して実際にFunc
というインスタンスを呼び出す式を作成する必要があります。そのため、std::result_of_t
は(C++ 14で、それは友好的SFINAEなります)があります:
template <typename Func, typename... Args,
class R = std::result_of_t<Func(Args...)>>
R delegate(Func, Args...);
あるいは、C++ 11には、ちょうどdecltype
とdeclval
とのことを書き出す:
template <typename Func, typename... Args,
class R = std::declval<Func>()(std::declval<Args>()...)>
R delegate(Func, Args...);
は
'result_of'はあなたが望み、かつ' INVOKE'の完全な可能性を使用しない限り、間違ったことです。 –
- 1. SFINAE std :: enable_if引数
- 2. 関数の引数とテンプレートの引数としてstd :: enable_ifを使用する違いは何ですか?
- 3. `std :: enable_if`は関数ポインタです - どうですか?
- 4. enable_if:引数のないvoidメンバ関数の最小例
- 5. のstd :: enable_ifは
- 6. std :: set比較関数のカスタム引数
- 7. std :: enable_if specialization failed
- 8. C++ 11 - テンプレートはstd :: enable_ifとstd ::
- 9. Barton-Nackman vs std :: enable_if
- 10. のstd ::関数の引数リストとのtypedefは
- 11. 関数ポインタから引数リストを引き出す方法は?
- 12. 可変テンプレートとstd :: enable_if
- 13. std :: tieとstd :: make_tupleのstd :: ref引数の違いは何ですか?
- 14. std :: varadicメンバ関数への関数とその後のバリデーションテンプレート引数のバインド
- 15. std :: mutexを引数としてメンバー関数をスレッディング
- 16. C++関数のstd :: vector引数(省略可能)
- 17. テンプレート引数とstd ::関数パラメータの控除
- 18. 部分テンプレート関数specialisation with enable_if:既定の実装を実装
- 19. 関数は、引数
- 20. std :: enable_if内でのsizeof ...の使用
- 21. std :: remove_if内のconst引数
- 22. C++ 11 std :: functionは、関数ポインタが持つことができる引数の数を制限しますか?
- 23. enable_ifと複数の条件の問題
- 24. 関数で引数を渡すには?
- 25. `std :: function`は引数を移動できますか?
- 26. テンプレート関数のテンプレート引数
- 27. std :: thread関数の引数としてifstreamを渡すにはどうすればよいですか?
- 28. Rは、関数の引数
- 29. 関数の引数は、データベーステーブル
- 30. は、関数の引数
はあなたでしょう正しく使用する方法を書き留めておきますか?または私にリンクを教えてください? – oconnor0
正確にSFINAEに何をしようとしていますか? –
私は、 'Func'が' Args ... 'に適用できる関数(できれば関数ポインタ)であるときに' delegate'を呼び出し可能にしようとしていました。私は最初のパラメータの型として 'Func *'を使いたいと思っています。 – oconnor0