2012-10-01 21 views
12

मैं बूस्ट :: एडेप्टर :: एडाप्टर में सी ++ 0x लैम्ब्डा प्रदान करके परिवर्तित करने की कोशिश कर रहा हूं।बूस्ट ट्रांसफर इटरेटर और सी ++ 11 लैम्ब्डा

निम्नलिखित कोड संकलित नहीं करता है। मैं बूस्ट 1.48 के साथ जी ++ 4.6.2 का उपयोग कर रहा हूं।

#include <iostream> 
#include <vector> 

#include <boost/range/adaptors.hpp> 
#include <boost/range/algorithm.hpp> 

using namespace std; 
namespace br = boost::range; 
namespace badpt = boost::adaptors; 


int main() 
{ 
    vector<int> a = {0,3,1,}; 
    vector<int> b = {100,200,300,400}; 

    auto my_ftor = [&b](int r)->int{return b[r];}; 

    cout<<*br::max_element(a|badpt::transformed(my_ftor))<<endl; 
} 

मैं यहां क्या गलत कर रहा हूं पर कोई विचार?

+0

आपने क्या त्रुटि मिलता है? – ronag

+0

http://stackoverflow.com/questions/12672372/boost-transform-iterator-and-c11-lambda संबंधित और एमबी डुप्लिकेट। – ForEveR

+0

त्रुटि लॉग विस्तृत है। कृपया [लिंक] देखें (http://pastebin.com/grsENb1m)। – Nithin

उत्तर

4

खैर lambdas अच्छा नहीं खेलते हैं, क्योंकि वे constructible डिफ़ॉल्ट नहीं कर रहे हैं, जो iterators के लिए आवश्यक है।

#define RETURNS(...) -> decltype(__VA_ARGS__) { return (__VA_ARGS__); } 

template<class Fun> 
struct function_object 
{ 
    boost::optional<Fun> f; 

    function_object() 
    {} 
    function_object(Fun f): f(f) 
    {} 

    function_object(const function_object & rhs) : f(rhs.f) 
    {} 

    // Assignment operator is just a copy construction, which does not provide 
    // the strong exception guarantee. 
    function_object& operator=(const function_object& rhs) 
    { 
     if (this != &rhs) 
     { 
      this->~function_object(); 
      new (this) function_object(rhs); 
     } 
     return *this; 
    } 

    template<class F> 
    struct result 
    {}; 

    template<class F, class T> 
    struct result<F(T)> 
    { 
     typedef decltype(std::declval<Fun>()(std::declval<T>())) type; 
    }; 

    template<class T> 
    auto operator()(T && x) const RETURNS((*f)(std::forward<T>(x))) 

    template<class T> 
    auto operator()(T && x) RETURNS((*f)(std::forward<T>(x))) 
}; 

template<class F> 
function_object<F> make_function_object(F f) 
{ 
    return function_object<F>(f); 
} 

तो फिर तुम सिर्फ यह कर सकते हैं:

int main() 
{ 
    vector<int> a = {0,3,1,}; 
    vector<int> b = {100,200,300,400}; 

    cout<<*br::max_element(a|badpt::transformed(make_function_object([&b](int r)->int{return b[r];};)))<<endl; 
} 
8

यह अच्छी तरह से ज्ञात मुद्दा है। यहाँ देखो

http://boost.2283326.n4.nabble.com/range-cannot-use-lambda-predicate-in-adaptor-with-certain-algorithms-td3560157.html

जल्दी ही आपको उपयोग decltype बजाय boost::result_of के लिए इस मैक्रो

#define BOOST_RESULT_OF_USE_DECLTYPE 

उपयोग करना चाहिए।

से here

उद्धरण अपने संकलक decltype का समर्थन करता है, तो आप स्वत: परिणाम प्रकार कटौती मैक्रो BOOST_RESULT_OF_USE_DECLTYPE को परिभाषित करने, निम्न उदाहरण में से सक्षम कर सकते हैं।

+1

हाय, जैसा कि मैं समझता हूं, यह 1.51 + को बढ़ावा देने के लिए लागू है। मैंने किसी भी बूस्ट हेडर को शामिल करने से पहले मैक्रो डालने का प्रयास किया लेकिन इसका कोई प्रभाव नहीं पड़ा। लिंक में अन्य समाधान भी बूस्ट/रेंज/नियमित एचपीपी की उपलब्धता मानते हैं जो बूस्ट-1.48 में उपलब्ध नहीं है। लिंक के लिए धन्यवाद। – Nithin

+1

@ इस मैक्रो को और अधिक त्रुटियों को ठीक करें, लेकिन त्रुटियां हैं, जिन्हें बिना किसी बूस्ट :: रेंज रीराइटिंग (डिफ़ॉल्ट सी-टोर (बूस्ट संस्करण 1.48) द्वारा फ़ैक्टर का निर्माण करने के लिए तय नहीं किया जा सकता है, उदाहरण के लिए बंद होने के साथ कभी काम नहीं करेगा)। बूस्ट :: transform_iterator के साथ बंद करने का उपयोग न करें अब – ForEveR

+0

ओह ठीक है! इनपुट के लिए धन्यवाद। मैं शायद @ पॉल के सुझाव के साथ जाऊंगा क्योंकि मैं वास्तव में अब बूस्ट संस्करण को नहीं बदल सकता। – Nithin

1

@ हमेशा के जवाब (#define BOOST_RESULT_OF_USE_DECLTYPE) मेरे लिए काम नहीं किया यहाँ एक आवरण मैं lambdas के लिए इस्तेमाल करते हैं। और @ पॉल का जवाब बहुत लंबा है (और बहुत सामान्य)। एक अधिक विशिष्ट समाधान हो सकता है:

#include <iostream> 
#include <vector> 

#include <boost/range/adaptors.hpp> 
#include <boost/range/algorithm.hpp> 

using namespace std; 
namespace br = boost::range; 
namespace badpt = boost::adaptors; 


int main() 
{ 
    vector<int> a = {0,3,1,}; 
    vector<int> b = {100,200,300,400}; 

    struct{ 
    vector<int>* bP;        //pointer, just to imitate lambda syntax... 
    int operator()(int r) const{return (*bP)[r];} //was my_ftor = [&b](int r)->int{return b[r];}; 
    } my_ftor{&b};         //...here 

    cout<<*br::max_element(a|badpt::transformed(my_ftor))<<endl; 
} 

(यह 2016 1.58 बूस्ट है और यह अभी भी टूटी हुई है कम से कम कैप्चर बिना लैम्ब्डा boost::transformed की आवश्यकताओं को पूरा करना चाहिए।।)

तो लैम्ब्डा नहीं था 'टी एक पर कब्जा (नहीं अपने मामले) है कोड थोड़ा सरल किया जाएगा या आप इस्तेमाल कर सकते हैं:

... 
int(*my_ftor)(int) = [](int r)->int{return ...;}; // function pointer default constructible and callable 
cout<<*br::max_element(a|badpt::transformed(my_ftor))<<endl; 
... 
संबंधित मुद्दे