template <class... Args>
void f(Args... args) {
auto l = [tup=std::make_tuple(std::move(args)...)] {
std::apply([](auto&&...args){
g(decltype(args)(args)...);
}, tup);
};
}
有點噁心。
將它們打包成一個元組,然後用std::apply
解開元組。如果您缺少std::apply
請自己寫一個等值的。
如果您想用rvalues調用g
,請將外部lambda設置爲mutable,並將move
元組設置爲內部lambda。
如果您想要訪問外部或類似的參數,內部lambda可以默認捕獲&
。
我們甚至可以抽象這種模式有點:
template<class F, class...Args>
auto forward_capture(F&& f, Args&&...args) {
return [
f=std::forward<F>(f),
tup=std::make_tuple(std::forward<Args>(args)...)
]{
return std::apply(f, tup);
};
}
使用:
template <typename... Args>
void f(Args... args) {
auto l = forward_capture(
[](auto&&...args) {
g(args...);
},
std::move(args)...
);
// use l
}
如果你想捕捉榜第一,我們可以做到這一點:
template<class...Args>
auto forward_capture(Args&&...args) {
return [
tup=std::make_tuple(std::forward<Args>(args)...)
](auto&& f)mutable{
return [
f=decltype(f)(f),
tup=std::move(tup)
]{
return std::apply(f, tup);
};
};
}
使用:
template <typename... Args>
void f(Args... args) {
auto l = forward_capture(std::move(args)...)(
[](auto&&...args) {
g(args...);
}
);
// use l
}
它具有我們有3個嵌套lambda的「優勢」。
更加有趣:
template<class...Args>
struct arrow_star {
std::tuple<Args...> args;
template<class F>
auto operator->*(F&& f)&& {
return [f=std::forward<F>(f),args=std::move(args)]()mutable{
return std::experimental::apply(std::move(f), std::move(args));
};
}
};
template<class...Args>
arrow_star<std::decay_t<Args>...> forward_capture(Args&&...args) {
return {std::make_tuple(std::forward<Args>(args)...)};
}
template<class...Args>
auto f(Args... args)
{
return
forward_capture(std::move(args)...)
->*
[](auto&&...args){
g(decltype(args)(args)...);
};
}
live example。
不是很漂亮,但作品:) – RiaD
@RiaD而我在這裏,這裏有2個變種。 ;) – Yakk
我有一個關於捕獲與初始值設定項的問題。我讀過它們主要是用於移動類型的,但是不能做'[x = std :: move(x)]'作爲引用然後移動 - >'[&] {std: :移動(X); }'?將其移入捕獲列表似乎對我未經訓練的眼睛來說是多餘的。 – 0x499602D2