2016-01-26 16 views
7

के सभी तर्कों ले जाएँ मैं लैम्ब्डा ऐसे ही तर्क के किसी भी संख्या को स्वीकार करेंगे बनाना चाहते हैं। अगर यह केवल 1 तर्क था तो मैंलैम्ब्डा

void f(Arg arg) { 
    auto l = [arg = std::move(arg)]() { 
     g(move(arg)); 
    } 
} 

सभी तर्कों को लैम्ब्डा में कैसे स्थानांतरित करें?

उत्तर

8
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); 
    }; 
} 

थोड़ा सा icky।

उन्हें एक ट्यूपल में पैक करें, फिर std::apply के साथ टपल अनपैक करें। यदि आपके पास std::apply की कमी है तो आप को समकक्ष लिखें।

यदि आप g को रावजू के साथ आमंत्रित करना चाहते हैं, तो बाहरी लैम्ब्डा म्यूटेबल बनाएं, और move आंतरिक लैम्ब्डा में टुपल करें।

आंतरिक लैम्ब्डा डिफ़ॉल्ट रूप से & पर कैप्चर कर सकता है यदि आप बाहरी या इसी तरह के तर्कों तक पहुंच चाहते हैं।

हम भी कर सकते हैं सार इस पैटर्न एक सा:

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 नेस्टेड लैम्ब्डा हैं।

या अधिक मज़ा:

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

+0

इतना सुंदर नहीं है, लेकिन काम करता है :) – RiaD

+0

@RiaD जबकि मैं इसमें हूं, यहां 2 प्रकार हैं। ;) – Yakk

+0

मेरे पास प्रारंभकर्ताओं के साथ कैप्चर के बारे में एक प्रश्न है। मैंने पढ़ा है कि वे मुख्य रूप से केवल-केवल प्रकार के लिए हैं, लेकिन '[x = std :: move (x)] करने का विकल्प नहीं हो सकता है, फिर संदर्भ लें ->' [&] {std: : इस कदम (x); } '? कैप्चर सूची में इसे स्थानांतरित करना मेरी अनियंत्रित आंखों के लिए अनावश्यक लगता है। – 0x499602D2

संबंधित मुद्दे