2011-12-12 13 views
8

मैं प्रकार रैपिंग ऊपर किसी प्रकार का एक समारोह है, शायद एक लैम्ब्डा समारोह है कहते हैं:क्या होता है जब लैम्ब्डा युक्त एक प्रकार असाइन किया जाता है?

template<typename Function> 
    struct my_struct 
{ 
    Function f; 

    my_struct(const Function &f) : f(f) {} 
}; 

जब इस प्रकार का एक उदाहरण असाइन किया गया है तो क्या होगा? मेरी समझ यह है कि लैम्बडा अपरिवर्तनीय हैं, और असाइनमेंट ऑपरेटरों को हटा दिया है।

फिर भी, जब मैं एक वस्तु के लिए नीचे दिए कोड स्निपेट में इस प्रकार के असाइन करें, कोई त्रुटि उत्सर्जित होता है:

$ g++-4.6 -std=c++0x test.cpp 
test.cpp: In member function ‘my_struct<Function>& my_struct<Function>::operator=(const my_struct<Function>&) [with Function = main()::<lambda(int)>, my_struct<Function> = my_struct<main()::<lambda(int)> >]’: 
test.cpp:34:25: instantiated from here 
test.cpp:13:5: error: use of deleted function ‘main()::<lambda(int)>& main()::<lambda(int)>::operator=(const main()::<lambda(int)>&)’ 
test.cpp:27:18: error: a lambda closure type has a deleted copy assignment operator 
:

// a structure which contains a function; 
// possibly a lambda function 
template<typename Function> 
    struct my_struct 
{ 
    Function f; 

    my_struct(const Function &f) : f(f) {} 

    // XXX adding this assignment operator causes an error 
    //my_struct &operator=(const my_struct &other) 
    //{ 
    // f = other.f; 
    // return *this; 
    //} 
}; 

template<typename Function> 
my_struct<Function> make_struct(const Function &f) 
{ 
    return my_struct<Function>(f); 
} 

int main() 
{ 
    // create some lambda 
    auto lambda = [](int x){return x;}; 

    // make a struct containing a copy of the lambda 
    auto x = make_struct(lambda); 

    // try to assign to the struct, which 
    // presumably assigns to the enclosed lambda 
    x = make_struct(lambda); 

    return 0; 
} 

टिप्पणी की-आउट असाइनमेंट ऑपरेटर जोड़ने में कोई त्रुटि, के रूप में उम्मीद की पैदावार

तो, क्या लैम्ब्डा सदस्य चर के साथ असाइन करने योग्य प्रकार बनाना संभव है? ऐसा करने के लिए एक उचित चीज़ की तरह लगता है। उदाहरण के लिए, boost::transform_iterator के साथ लैम्ब्डा को संयोजित करने पर विचार करें।

+2

मुझे अभी तक जाने के बारे में बहुत कुछ पता नहीं है, लेकिन क्या यह संभव है कि उन्हें स्थानांतरित किया जा सके लेकिन कॉपी नहीं किया जा सके? आप पहले से ही इसका जवाब जान सकते हैं, लेकिन मैं हिल-सीटर्स के बारे में जानकार नहीं हूं, इसलिए यदि आप करते हैं, तो कृपया बताएं। –

+0

विचार के लिए धन्यवाद, लेकिन एक चाल ऑपरेटर शुरू करने से त्रुटि संदेश नहीं बदल रहा था। स्पष्टीकरण के लिए –

उत्तर

12

आप करीब हैं। एक लैम्ब्डा में एक निहित प्रति-निर्माता होता है और हो सकता है - कैप्चर किए गए मूल्यों के आधार पर - एक अंतर्निहित चाल-निर्माता। इसमें एक हटाए गए प्रति-असाइनमेंट ऑपरेटर हैं।

दूसरे शब्दों में, आप इसे बना सकते हैं, लेकिन आप इसे असाइन नहीं कर सकते हैं। यदि आप एक सामान्य फ़ंक्शन ऑब्जेक्ट की तलाश में हैं, तो आप std::function<> का उपयोग करना चाहते हैं। यह कार्यों को प्रथम श्रेणी के मूल्यों के रूप में अनुकरण करता है।


ध्यान दें कि अपरिवर्तनीय असाइन करने योग्य से अलग है। एक लैम्ब्डा परिवर्तनशील बुलाया जाता है, तो इसका मतलब है कि अपने कार्य-कॉल शरीर लैम्ब्डा के सदस्यों को संशोधित कर सकते हैं (जैसे, समारोह नहीं const है):

int i = 0; 

auto okay = [=](int x) mutable { i += x; }; 
auto error = [=](int x) { i += x; }; 

इनमें से प्रत्येक कॉपी-constructable और गैर-आबंटित है।

+3

धन्यवाद। यह बहुत खराब असाइनमेंट हटा दिया गया है - ऐसा लगता है कि कम से कम वर्तमान कार्यान्वयन के साथ लैम्ब्डा को '' बूस्ट :: ट्रांसफॉर्म_इटरेटर''' के साथ असंगत बनाना है। –

+0

अन्य कार्यवाही के लिए [यह जवाब] देखें (http://stackoverflow.com/a/35412456/554283) (std :: ref, प्रस्तावित बूस्ट फ़िट लाइब्रेरी, और प्रस्तावित बूस्ट रेंज एक्सटेंशन लाइब्रेरी का उपयोग करके)। –

+0

लेकिन फिर std :: function कैसे lambda की एक प्रति बना सकता है? –

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

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