2015-12-30 9 views
5

次コンパイルあいまいです:は「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

'using namespace std'や' std :: makes_shared'を使っていますか? –

答えて

12

my_fnのタイプは、名前空間stdに存在する、std::function<void()>;です。

に電話をかけようとすると、(あなたがusing boost::make_shared;を書いたので)ブースト版とADLによって標準版が表示されます。

intstdに属していません。make_sharedという名前空間と標準バージョンは考慮されていません。

このような問題を避けるために可能な場合は修飾名を使用することをお勧めします。

+0

ありがとうございます。私は残念な質問が1つあります。以下のように動作します: "shared_ptr > k = make_shared >(0);"私はADLがここではうまくいかないのだろうかと思っていますが、std :: stringのようなstdの他のものではそうです。 –

+0

@GaryJackson ADLは関数の引数として機能します。あなたの例では、引数は 'int'で' ADLを引き起こさない '0です。 –

+2

うまくいけば、ADLはADLのないその名前の関数テンプレートを見つけたときにここにたどり着きます。[here](http://stackoverflow.com/questions/2953684/why-doesnt-adl-find-functionテンプレート)。これを自分でテストすることができます - 'boost :: make_shared'のためのusingステートメントを削除することで、準拠しているコンパイラが' std :: make_shared'を見つけることができなくなります。 – jaggedSpire

関連する問題