関数を型にバインドしようとしています-次のテストプログラムを検討してください:
#include <utility>
template <class Ret, class Arg>
struct func {
typedef Ret (&ref)(Arg);
template <ref Fn>
struct bind {
template <class NewArg>
Ret operator()(NewArg&& arg) {
return Fn(std::forward<Arg>(arg));
}
};
};
int foo(int i) {
return i;
}
typedef func<int, int>::bind<foo> Foo;
int main(int argc, char** argv) {
Foo foo_obj;
return foo_obj(argc);
}
これは機能しますが、私は個人的にfunc<int, int>::bind<foo>
醜く、冗長でもあります-しかし、私はそうすることができないようで、func::bind<foo>
RetとArgをテンプレート引数から推論してバインドします(または道徳的に同等のもの)。私はこのようなことをします:
template <class Ret, class Arg>
constexpr auto bind_func(typename func<Ret, Arg>::ref f) -> typename func<Ret, Arg>::bind<f> {
return {};
}
ただし、fが定数式であることが保証されていないため、コンパイラはfが有効なテンプレート引数であることを認識できないため、コンパイルできません。
一定の冗長性なしでこれを達成する方法はありますか?