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);
};
}
Một chút icky.
Đóng gói chúng thành một bộ, sau đó giải nén tuple bằng std::apply
. Nếu bạn thiếu std::apply
hãy viết cho mình một tài khoản tương đương.
Nếu bạn muốn gọi g
với giá trị, hãy tắt lambda bên ngoài và move
tuple vào lambda bên trong.
Bên trong lambda có thể chụp theo mặc định &
nếu bạn muốn truy cập vào args của bên ngoài hoặc tương tự.
Chúng tôi thậm chí có thể trừu tượng mô hình này một chút:
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);
};
}
sử dụng:
template <typename... Args>
void f(Args... args) {
auto l = forward_capture(
[](auto&&...args) {
g(args...);
},
std::move(args)...
);
// use l
}
Nếu bạn muốn danh sách chụp đầu tiên, chúng ta có thể làm điều đó:
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);
};
};
}
sử dụng :
template <typename... Args>
void f(Args... args) {
auto l = forward_capture(std::move(args)...)(
[](auto&&...args) {
g(args...);
}
);
// use l
}
trong đó có "lợi thế" mà chúng tôi có 3 lambd lồng nhau.
Hoặc chi tiết thú vị:
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.
Không đẹp, nhưng hoạt động :) – RiaD
@RIAD trong khi tôi đang ở đó, đây là 2 biến thể. ;) – Yakk
Tôi có câu hỏi về các lần chụp bằng trình khởi tạo. Tôi đọc rằng chúng chủ yếu dùng cho các kiểu di chuyển, nhưng không thể thay thế để làm '[x = std :: move (x)]' là lấy một tham chiếu rồi di chuyển -> '[&] {std: : di chuyển (x); } '? Di chuyển nó trong danh sách chụp có vẻ dư thừa với đôi mắt chưa được đào tạo của tôi. – 0x499602D2