[英]C++17 decorate lambda or member function with non-capturing lambda
我正在嘗試制作一個 function,它返回一個非捕獲 lambda(因此它可以轉換為一個 function 指針)裝飾一個內部 function,其中內部 function 可以是 8835508.86348 指針或 84a71988 指針
Compiler Explorer 鏈接供參考,我將在下面對其進行剖析。
我提出了兩種策略,一種用於 lambda,另一種用於成員函數。 具體來說,對於 lambda
template <typename Callable>
auto decorate_lambda(Callable&& lambda) {
static const Callable callable = std::forward<Callable>(lambda);
return [](auto... args) {
return 100 + callable(std::forward<decltype(args)>(args)...);
};
}
將 lambda 保存為static
允許在非捕獲 lambda 中使用callable
。這很好,因為decorate_lambda
模板實例化對於每個 lambda (IIRC) 都是唯一的。
對於成員函數,策略有些不同(注意模板參數)
template <auto callable>
auto decorate_memfn() {
return [](auto... args) {
return 100 + std::mem_fn(callable)(std::forward<decltype(args)>(args)...);
};
}
然后我可以做類似的事情
const auto decorated_lambda =
decorate_lambda([](int i) { return i + 1; });
const auto decorated_memfn =
decorate_memfn<&Worker::work>();
int (*lambda_fnptr)(int) = decorated_lambda;
int (*memfn_fnptr)(Worker&, int) = decorated_memfn;
導致 function 指針可用於例如 C 接口(最終)。
我想要的最終結果是將decorate_lambda
和decorate_memfn
滾動到單個decorate(lambda_or_memfn)
function (使用模板專業化, if constexpr
,或其他)。 例如
decorate([](int i) { return i + 1; });
decorate(&Worker::work);
即基本上我想要decorate_memfn(&Worker::work)
而不是decorate_memfn<&Worker::work>()
。 問題是
decorate_memfn
中的靜態/全局變量。 有沒有辦法強制編譯器識別參數來自靜態/全局參數,從而允許它在 lambda 中使用而不捕獲?static
技巧做一些類似於decorate_lambda
的事情對成員 function 指針不起作用,因為模板實例化不一定是唯一的(即如果兩個Callable
具有相同的簽名)。 不過,也許有辦法讓它變得獨一無二?我知道 C++20 可以提供幫助,但不幸的是我被 C++17 困住了。
非常感謝任何提示!
首先,你的decorate_lambda
有問題:如果你用有狀態的可調用函數調用它,它會無聲地中斷。 作為一個簡單的檢查,您可以僅在std::is_empty_v
為真時才允許調用。
我想要的最終結果是將 decorate_lambda 和 decorate_memfn 合並為一個 decorate(lambda_or_memfn) function
您可以使用std::integral_constant
template<auto x>
inline constexpr std::integral_constant<decltype(x), x> constant{};
template<typename T, typename F, F T::* x>
auto decorate(std::integral_constant<F T::*, x>)
{
return [](auto&&... args) {
return 100 + std::mem_fn(x)(decltype(args)(args)...);
};
}
auto d = decorate(constant<&Worker::work>);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.