'make_shared' is ambiguous

The following compilation if B0RKEN is not defined (for example, with -DB0RKEN on the command line):

#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 } 

It seems that boost is playing fun games, and that is probably why this piece of code has this problem. I do not understand why it works with shared_ptr<int> , but not shared_ptr<my_fn> .

I am not interested in discussing whether I should use boost or std shared pointers.

I get the following error from clang ++:

 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. 

And from g ++:

 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) ^ 
+5
source share
1 answer

Type my_fn - std::function<void()>; located in the std .

When you try to call make_shared<my_fn>(fn); , he sees either the accelerated version (because you wrote using boost::make_shared; ) or the std version due to ADL.

int does not belong to the std , and the std version of make_shared not considered.

Instead, use qualified names to avoid such problems.

+12
source

Source: https://habr.com/ru/post/1239500/


All Articles