関数オブジェクトを関数ポインタに変換する方法を探しています。キャプチャレス ラムダには、次のことを可能にする暗黙的な変換があります。
using fptr_t = int (*)(int);
fptr_t ptr = nullptr;
ptr = [](int) { return 2; };
ptr = [](auto) { return 3; };
(*ptr)(42);
私は次のような昔ながらの空のクラス関数オブジェクトで同じことをしようとしています:
struct Foo {
int operator()(int) const { return 5; }
} foo;
またはstd::less<int>
.
私が見つけた 1 つの方法は、呼び出しfoo
をラムダでラップすることです。それがステートレスで const であることを保証できれば、このptr と lambda-capturefoo
は本当に必要ありません。
template <typename R, typename... Args>
struct to_function_pointer<R(Args...)> {
private:
template <typename T, REQUIRES(std::is_empty<T>::value)>
static T const& stateless_const() {
return (*static_cast<T const*>(nullptr));
}
public:
using pointer = R (*)(Args...);
template <typename U>
pointer operator()(U) const {
return [](Args... args) {
return stateless_const<std::decay_t<U>>()(args...);
};
}
};
しかし、ここでは、完全な転送を提供する方法がわかりません。原因[](Args&&...)
または[](auto&&...)
変換できませんR(*)(Args...)
。args が のようにコピーできない場合、このようなトリックは失敗しますstd::unique_ptr<int>
。
を使用できることはわかっていますstd::function
が、軽量のソリューションを取得しようとしている間、それは一種の重量です。
実例。
アドバイスをいただければ幸いです。