2012-05-27 16 views
21

मुझे यह पता लगाने में परेशानी हो रही है कि बिल्ली यह संकलन क्यों नहीं कर रहा है। मुझे कुछ लैम्ब्डा फ़ंक्शन मिला है जो कुछ तर्क के आधार पर std::function देता है।std :: बाध्य फ़ंक्शन बाध्य करें

मैं इस स्निपेट को अपनी समस्या को संकुचित होता है (जो lambdas का उपयोग नहीं करता है, लेकिन पूरी तरह से मेरी त्रुटि reproduces):

#include <functional> 
#include <iostream> 


struct foo { 
    template<class T> 
    void bar(T data) { 
     std::cout << data << "\n"; 
    } 
}; 

void some_fun(const std::function<void(int)> &f) { 
    f(12); 
} 

int main() { 
    foo x; 
    auto f = std::bind(&foo::bar<int>, x, std::placeholders::_1); 
    auto w = std::bind(some_fun, f); 
    w(); 
} 

w() करने के लिए कॉल उन सुंदर जीसीसी त्रुटि आउटपुट में से एक का उत्पादन है, जिसमें मैं यह नहीं समझ सकता कि क्या गलत हो रहा है।

g++ -std=c++0x test.cpp -o test 
test.cpp: In function ‘int main()’: 
test.cpp:20:7: error: no match for call to ‘(std::_Bind<void (*(std::_Bind<std::_Mem_fn<void (foo::*)(int)>(foo, std::_Placeholder<1>)>))(const std::function<void(int)>&)>)()’ 
/usr/include/c++/4.6/functional:1130:11: note: candidates are: 
/usr/include/c++/4.6/functional:1201:2: note: template<class ... _Args, class _Result> _Result std::_Bind<_Functor(_Bound_args ...)>::operator()(_Args&& ...) [with _Args = {_Args ...}, _Result = _Result, _Functor = void (*)(const std::function<void(int)>&), _Bound_args = {std::_Bind<std::_Mem_fn<void (foo::*)(int)>(foo, std::_Placeholder<1>)>}] 
/usr/include/c++/4.6/functional:1215:2: note: template<class ... _Args, class _Result> _Result std::_Bind<_Functor(_Bound_args ...)>::operator()(_Args&& ...) const [with _Args = {_Args ...}, _Result = _Result, _Functor = void (*)(const std::function<void(int)>&), _Bound_args = {std::_Bind<std::_Mem_fn<void (foo::*)(int)>(foo, std::_Placeholder<1>)>}] 
/usr/include/c++/4.6/functional:1229:2: note: template<class ... _Args, class _Result> _Result std::_Bind<_Functor(_Bound_args ...)>::operator()(_Args&& ...) volatile [with _Args = {_Args ...}, _Result = _Result, _Functor = void (*)(const std::function<void(int)>&), _Bound_args = {std::_Bind<std::_Mem_fn<void (foo::*)(int)>(foo, std::_Placeholder<1>)>}] 
/usr/include/c++/4.6/functional:1243:2: note: template<class ... _Args, class _Result> _Result std::_Bind<_Functor(_Bound_args ...)>::operator()(_Args&& ...) const volatile [with _Args = {_Args ...}, _Result = _Result, _Functor = void (*)(const std::function<void(int)>&), _Bound_args = {std::_Bind<std::_Mem_fn<void (foo::*)(int)>(foo, std::_Placeholder<1>)>}] 

यहाँ, f कुछ प्रतिदेय वस्तु जो तर्क के रूप में एक पूर्णांक लेता है और इसे का उपयोग कॉल किया जाना चाहिए: यह जीसीसी 4.6.1 द्वारा गूँजती त्रुटि है। दूसरी तरफ, w केवल एक कॉल करने योग्य ऑब्जेक्ट है जो some_fun(f) पर कॉल करता है, f ऊपर उल्लिखित कॉल करने योग्य ऑब्जेक्ट होने पर, some_fun के पैरामीटर द्वारा हस्ताक्षर अपेक्षित है।

क्या मुझे कुछ याद आ रही है? मुझे शायद यह नहीं पता कि वास्तव में std::bind और std::function कैसे मिलाएं।

+2

यह है जब आप 'std :: समारोह ' च के लिए के साथ ऑटो की जगह काम करने के लिए लगता है। – Lalaland

+2

यह आपकी समस्या का उत्तर नहीं हो सकता है .. लेकिन आप देशी लैम्ब्डा-कार्यों सी ++ 11 (जो कर एसटीडी अनावश्यक बाँध ::) के साथ आ रहा है का उपयोग कर विचार किया है? – coldfix

+4

बूस्ट में हमारे पास इस तरह के मामलों के लिए 'रक्षा' है, लेकिन ऐसा लगता है कि यह मानक को नहीं बना रहा है। –

उत्तर

21

std::bind भाव, उनकी boost::bind पूर्ववर्तियों की तरह, रचना ऑपरेशन का एक प्रकार का समर्थन। w के लिए आपका अभिव्यक्ति मोटे तौर पर इस तरह से

auto w=std::bind(some_fun, std::bind(&foo::bar<int>, x, std::placeholders::_1)); 

नेस्टिंग बांध के बराबर के रूप

  1. व्याख्या की है x.bar<int>(y) का मूल्य जहां y पहले पैरामीटर जिसके परिणामस्वरूप functor में पारित कर दिया है की गणना है।
  2. परिणामस्वरूप some_fun पर जाएं।

लेकिन x.bar<int>(y) शून्य कार्य देता है, कोई फ़ंक्शन प्रकार नहीं। यही कारण है कि यह संकलित नहीं करता है।

के-बॉलो boost::bind के साथ बताते हैं, तो आप boost::protect के साथ इस समस्या को ठीक कर सकते हैं। जैसा कि केरेक एसबी और ildjarn बताते हैं, इस मुद्दे के आसपास एक तरीका है: f के लिए auto का उपयोग न करें। आप बाइंड अभिव्यक्ति के प्रकार के लिए f नहीं चाहते हैं। यदि f में कोई अन्य प्रकार है, तो std::bind फ़ंक्शन संरचना नियमों को लागू करने का प्रयास नहीं करेगा।तुम्हें पता है, उदाहरण के लिए, f दे सकता है प्रकार std::function<void(int)>:

std::function<void(int)> f = std::bind(&foo::bar<int>, x, std::placeholders::_1); 
auto w = std::bind(some_fun, f); 

f के बाद से सचमुच एक बाँध अभिव्यक्ति के प्रकार नहीं है, std::is_bind_expression<>::valuef के प्रकार पर झूठे हो जाएगा, और इतने में std::bind अभिव्यक्ति दूसरी पंक्ति फ़ंक्शन संरचना नियमों को लागू करने के प्रयास के बजाय, वर्बैटिम पर मान को पास कर देगी।

-3

some_funconst std::function<void(int)> & प्रकार का तर्क चाहता है।

std :: बाइंड "अनिर्दिष्ट प्रकार टी का एक फ़ंक्शन ऑब्जेक्ट" प्रदान करता है (प्रदान किया गया लिंक, अनुभाग "वापसी मूल्य" देखें), कि आप कुछ_फुन तर्क के रूप में पास करने का प्रयास कर रहे हैं।

ऐसा लगता है कि यह समस्या का कारण बनता है, क्योंकि इस तर्क प्रकार की अपेक्षा नहीं है।

देखो पर: http://en.cppreference.com/w/cpp/utility/functional/bind

+2

यह अंतर्निहित समस्या नहीं है - 'std :: is_bind_expression <>' और इसका व्यवहार है। – ildjarn

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