2015-12-30 115 views
5

下編譯除非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>

我不關心我是否應該使用boost或std共享指針。

我從鐺++得到以下錯誤:

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. 

而且從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) 
    ^
+0

什麼編譯器,什麼錯誤信息,什麼boost版本? – rhashimoto

+0

你有'使用命名空間std'或'使用std :: makes_shared'嗎? –

回答

12

類型的my_fnstd::function<void()>;,居住在命名空間std

當您嘗試呼叫時,它會憑藉ADL同時看到升級版本(因爲您編寫了using boost::make_shared;)和標準版本。

int不屬於std命名空間和標準版make_shared不考慮。

爲避免出現此類問題,請儘可能使用限定名稱。

+0

謝謝。我有一個縈繞不定的問題。以下工作:「shared_ptr > k = make_shared >(0);」。我想知道爲什麼ADL不在這裏踢,但它爲std中的其他東西(如std :: string)。 –

+0

@GaryJackson ADL適用於函數參數。在你的例子中,參數是'0',它是'int',不會觸發ADL。 –

+2

有趣的是,ADL將*只*在這裏踢,當它發現一個沒有ADL的名稱的函數模板,如[這裏]解釋(http://stackoverflow.com/questions/2953684/why-doesnt-adl-find-function -templates)。你可以自己測試 - 刪除'boost :: make_shared'的使用語句將會阻止符合的編譯器找到'std :: make_shared'。 – jaggedSpire