c++ - "मेक_फंक्शन" के लिए लैम्ब्डा के कॉल हस्ताक्षर या मनमाने ढंग से कॉल करने योग्य




function lambda (2)

कुछ परिस्थितियों में यह mem_fn योग्य (उदाहरण के लिए फ़ंक्शन, फ़ंक्शन पॉइंटर, operator() , लैम्ब्डा, mem_fn साथ ऑब्जेक्ट इंस्टेंस operator() टाइप करने में सक्षम होना वांछनीय है, उदाहरण के लिए सी ++ 11 mem_fn साथ बूस्ट एडेप्टर का उपयोग करने में जहां एक कॉपी-असाइन करने योग्य और डिफ़ॉल्ट-रचनात्मक प्रकार की आवश्यकता है।

std::function आदर्श होगा, लेकिन क्लास टेम्पलेट std::function को तत्काल करने के लिए स्वचालित रूप से निर्धारित करने का कोई तरीका नहीं है। क्या मनमाने ढंग से कॉल करने योग्य और / या उपयुक्त std::function make_function इंस्टेंस (यानी एक make_function फ़ंक्शन टेम्पलेट) में फ़ंक्शन हस्ताक्षर प्राप्त करने का कोई आसान तरीका है?

विशेष रूप से, मैं एक या दूसरे की तलाश में हूं

template<typename F> using get_signature = ...;
template<typename F> std::function<get_signature<F>> make_function(F &&f) { ... }

जैसे कि make_function([](int i) { return 0; }) एक std::function<int(int)> । स्पष्ट रूप से यह काम करने की उम्मीद नहीं की जाएगी यदि एक उदाहरण एक से अधिक हस्ताक्षर के साथ कॉल करने योग्य है (उदाहरण के लिए एक से अधिक, टेम्पलेट या डिफ़ॉल्ट-पैरामीटर operator() एस)।

बूस्ट ठीक है, हालांकि गैर-बूस्ट समाधान जो अत्यधिक जटिल नहीं होते हैं उन्हें प्राथमिकता दी जाती है।

संपादित करें: मेरे अपने प्रश्न का उत्तर दें।


असंभव। आप कुछ प्रकार के लिए operator() का पता ले सकते हैं, लेकिन मनमाने ढंग से कॉल करने योग्य नहीं, क्योंकि इसमें अधिभार या टेम्पलेट पैरामीटर हो सकते हैं। चाहे वह लैम्ब्डा के लिए काम करे या नहीं, निश्चित रूप से अच्छी तरह परिभाषित नहीं है, AFAIK।


गैर-परिवर्तनीय गैर-जेनेरिक कैप्चरलेस लैम्ब्डा फ़ंक्शंस के साथ-साथ सरल मुक्त फ़ंक्शंस के लिए कोई निम्न दृष्टिकोण का उपयोग कर सकता है:

#include <iostream>

#include <cstdlib>

template< typename L, typename R, typename ...A >
constexpr
auto // std::function< R (A...) >
to_function_pointer(L l, R (L::*)(A...) const)
{
    return static_cast< R (*)(A...) >(l);
}

template< typename L, typename R, typename ...A >
constexpr
auto // std::function< R (A...) >
to_function_pointer(L l, R (L::*)(A...)) // for mutable lambda
{
    return static_cast< R (*)(A...) >(l);
}

template< typename L >
constexpr
auto
to_function_pointer(L l)
{
    return to_function_pointer(l, &L::operator ());
}

template< typename R, typename ...A >
constexpr
auto // std::function< R (A...) >
to_function_pointer(R (* fp)(A...))
{
    return fp;
}

namespace
{

void f() { std::cout << __PRETTY_FUNCTION__ << std::endl; }

}

int
main()
{
    to_function_pointer([] () { std::cout << __PRETTY_FUNCTION__ << std::endl; })();
    //to_function_pointer([&] () { std::cout << __PRETTY_FUNCTION__ << std::endl; })(); // can't cast from non-captureless lambda to function pointer
    to_function_pointer([] () mutable { std::cout << __PRETTY_FUNCTION__ << std::endl; })();
    to_function_pointer(f)();
    to_function_pointer(&f)();
    return EXIT_SUCCESS;
}




type-inference