的super_func
是無狀態的函數對象,可以轉換到任何兼容的通話簽名。
template<class T>using type=T;
template<class Sig, Sig* func>
struct super_func;
template<class R, class...Args, R(*func)(Args...)>
struct super_func<R(Args...), func> {
using Sig = R(Args...);
using pSig = Sig*;
template<class R2, class...Args2, class=std::enable_if_t<
std::is_convertible<
std::result_of_t<pSig(Args2...)>,
R2
>{}
&& !std::is_same<R2, void>{}
>>
constexpr operator type<R2(Args2...)>*() const {
return [](Args2...args)->R2{
return func(std::forward<Args2>(args)...);
};
}
template<class...Args2, class=std::enable_if_t<
std::is_same<
std::result_of_t<pSig(Args2...)>,
R
>{}
>>
constexpr operator type<void(Args2...)>*() const {
return [](Args2...args)->void{
func(std::forward<Args2>(args)...);
};
}
constexpr operator pSig() const {
return func;
}
constexpr R operator()(Args...args)const{
return func(std::forward<Args>(args)...);
}
};
live example。 A super_func
是無狀態的。要使用它的函數foo,做到:
super_func< decltype(foo), &foo > super_foo;
,你會得到一個可調用無狀態空的對象,它的行爲很像0做,除非你可以把它分配給一個指針到任何兼容的函數指針,它產生它在編譯時「即時」。
A super_foo
可以餵給你的功能對象。
沒有外部幫助,在飛行中這樣做不起作用,因爲我們需要foo
成爲一個真正的靜態位信息。當它成爲一個變量的時候,這種無狀態的做法爲時已晚,所以我們不能使用lambda技巧(沒有額外的pvoid)爲我們想要的確切簽名生成一個函數指針。
你可以做一個宏:
#define SUPER(X) super_func< decltype(X), &X >{}
,然後用function<double()> f(SUPER(foo));
創建function
對象的另一種方法是存儲一個額外的指針的價值狀態,創造「以最快的速度代表「式擦除。 (該術語可以用於許多實現中的一個,每個實現都比上一個更快)。
如果你的函數類可以包含任意的可調用對象(如'std :: function'),這個特性是免費的。 – sbabbi
我想我可以實現這種類型的擦除成語,但有沒有另一種解決方案? (因爲類型擦除的經典實現將導致我動態分配內存) – eucpp
@EvgeniyMoiseenko嗯,你可以選擇只接受函數指針並將它們保存在一個'void *'中。 – Columbo