Ну, вы можете подождать C++ 17.
template<auto F>
struct function_ptr;
template<class R, class...Args, R(*F)(Args...)>
struct function_ptr<F> {
using signature = R(Args...);
constexpr R operator()(Args...args)const {
return F(std::forward<Args>(args)...);
}
constexpr operator signature*() const { return F; }
constexpr signature* operator+() const { return F; }
};
Сейчас:
constexpr auto f_ = []()->int { return 4; };
function_ptr<+f_> f;
генерирует функцию-указатель, как f
.
template<class T>struct tag_t {};
template<class F, class...Fs, class R, class...Args>
constexpr auto chain_functions(tag_t<R(Args...)>) {
constexpr r = [](Args...args)->R{
return F{}(Fs{}..., std::forward<Args>(args)...);
};
return function_ptr<+r>{};
}
позволяет нам цепочки функций указателей.
constexpr auto f_ = []()->int { return 4; };
function_ptr<+f_> f0;
constexpr auto g_ = [](int(*f)())->int { return f(); });
function_ptr<+g_> g_raw;
auto g0 = chain_functions< function_ptr<+g_>, function_ptr<+f_> >(tag_t<int()>{});
Теперь g
является function_ptr
.
int(*g)() = g0;
следует надеяться скомпилировать и работать. (Не тестировалось, у меня нет доступа к достаточно компилятору C++ 17).
По-прежнему немного тупой, и определенно не проверен. В основном function_ptr
предназначен для создания типа, который содержит указатель функции времени компиляции. C++ 17 предоставляет нам constexpr
lambdas, включая возможность вывести из них указатель функции в контексте constexpr
.
Затем мы можем скомпоновать эти типы указателей функций для генерации нового типа указателя функции.
Если это область видимости пространства имен, вы можете просто опустить 'f' из списка захвата. –