2015-12-30 8 views
5

निम्नलिखित compiles है, जब तक B0RKEN (-DB0RKEN कमांड लाइन पर के साथ) की तरह परिभाषित किया गया है:'make_shared' अस्पष्ट

#include <functional> 
#include <boost/shared_ptr.hpp> 
#include <boost/make_shared.hpp> 

using boost::shared_ptr; 
using boost::make_shared; 

using my_fn = std::function<void()>; 

void foo() 
{ 
     my_fn fn = [](){}; 

#ifdef B0RKEN 
     shared_ptr<my_fn> k = make_shared<my_fn>(fn); 
#else 
     shared_ptr<int> k = make_shared<int>(0); 
#endif 
} 

यह बढ़ावा तरह लगता है कुछ अजीब खेल, यही वजह है कि इस कोड टुकड़ा हो सकता है खेल रहा है इस मुद्दे में है। मुझे समझ में नहीं आता है कि यह shared_ptr<int> के साथ क्यों काम करता है लेकिन shared_ptr<my_fn> नहीं।

मुझे बहस में दिलचस्पी नहीं है कि मुझे बूस्ट या स्टडी साझा पॉइंटर्स का उपयोग करना चाहिए या नहीं।

मैं बजना ++ से निम्न त्रुटि मिलती है:

foo.cpp:15:24: error: call to 'make_shared' is ambiguous 
     shared_ptr<my_fn> k = make_shared<my_fn>(fn); 
           ^~~~~~~~~~~~~~~~~~ 
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/memory:4670:1: note: candidate function [with _Tp = 
     std::__1::function<void()>, _Args = <std::__1::function<void()> &>] 
make_shared(_Args&& ...__args) 
^ 
/opt/local/include/boost/smart_ptr/make_shared_object.hpp:246:87: note: candidate function [with T = std::__1::function<void()>, Args = 
     <std::__1::function<void()> &>] 
template< class T, class... Args > typename boost::detail::sp_if_not_array<T>::type make_shared(Args && ... args) 
                        ^
1 error generated. 

और जी ++ से:

foo.cpp: In function ‘void foo()’: 
foo.cpp:15:45: error: call of overloaded ‘make_shared(my_fn&)’ is ambiguous 
    shared_ptr<my_fn> k = make_shared<my_fn>(fn); 
              ^
foo.cpp:15:45: note: candidates are: 
In file included from PATH_TO_TOOLCHAIN/boost-1.59.0/include/boost/smart_ptr/make_shared.hpp:15:0, 
       from PATH_TO_TOOLCHAIN/boost-1.59.0/include/boost/make_shared.hpp:15, 
       from foo.cpp:3: 
PATH_TO_TOOLCHAIN/boost-1.59.0/include/boost/smart_ptr/make_shared_object.hpp:246:87: note: typename boost::detail::sp_if_not_array<T>::type boost::make_shared(Args&& ...) [with T = std::function<void()>; Args = {std::function<void()>&}; typename boost::detail::sp_if_not_array<T>::type = boost::shared_ptr<std::function<void()> >] 
template< class T, class... Args > typename boost::detail::sp_if_not_array<T>::type make_shared(Args && ... args) 
                        ^
In file included from PATH_TO_TOOLCHAIN/gcc-4.9.3/include/c++/4.9.3/memory:82:0, 
       from PATH_TO_TOOLCHAIN/boost-1.59.0/include/boost/config/no_tr1/memory.hpp:21, 
       from PATH_TO_TOOLCHAIN/boost-1.59.0/include/boost/smart_ptr/shared_ptr.hpp:23, 
       from PATH_TO_TOOLCHAIN/boost-1.59.0/include/boost/shared_ptr.hpp:17, 
       from foo.cpp:2: 
PATH_TO_TOOLCHAIN/gcc-4.9.3/include/c++/4.9.3/bits/shared_ptr.h:600:5: note: std::shared_ptr<_Tp1> std::make_shared(_Args&& ...) [with _Tp = std::function<void()>; _Args = {std::function<void()>&}] 
    make_shared(_Args&&... __args) 
    ^
+0

क्या कंपाइलर, क्या त्रुटि संदेश, क्या संस्करण संस्करण? – rhashimoto

+0

क्या आपके पास 'नामस्थान std' या' std :: makes_shared' का उपयोग कर रहा है? –

उत्तर

12

my_fn के प्रकार std::function<void()>; है, नाम स्थान std में रहने वाले।

जब आप पर कॉल करने का प्रयास करते हैं तो यह दोनों बूस्ट संस्करण को देखता है (क्योंकि आपने using boost::make_shared; लिखा था) और एडीएल के आधार पर std संस्करण।

intstdmake_shared के नामस्थान और std संस्करण से संबंधित नहीं है।

ऐसी समस्याओं से बचने के लिए संभव होने पर योग्य नामों का उपयोग करना पसंद करते हैं।

+0

धन्यवाद। मेरे पास एक लम्बे सवाल हैं। निम्नलिखित काम करता है: "shared_ptr > k = make_shared > (0),"। मुझे आश्चर्य है कि एडीएल यहां क्यों नहीं लाता है, लेकिन यह अन्य चीजों के लिए std (जैसे std :: string) के लिए करता है। –

+0

@GaryJackson एडीएल फ़ंक्शन तर्कों के लिए काम करता है। आपके उदाहरण में, तर्क '0' है जो 'int' है और एडीएल को ट्रिगर नहीं करता है। –

+2

Amusingly, ADL होगा * केवल * यहाँ में लात जब यह ADL बिना उस नाम का कोई समारोह टेम्पलेट पाता है, रूप में समझाया [यहां] (http://stackoverflow.com/questions/2953684/why-doesnt-adl-find-function -templates)। आप इसे स्वयं जांच सकते हैं - 'boost :: make_shared' के लिए उपयोग कथन को हटाने से एक अनुरूप कंपेलर को' std :: make_shared' ढूंढने से रोक दिया जाएगा। – jaggedSpire

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