2016-07-22 8 views
4

私はこの小さなmweにboost::pythonライブラリを使用しています。次のコードは `C++ 03`でコンパイルされますが、` C++ 11`ではコンパイルされません

#include <deque> 
#include <boost/python.hpp> 

typedef std::deque<long unsigned int> DequeUInt64; 

BOOST_PYTHON_MODULE_INIT(tmp) { 

boost::python::class_<DequeUInt64>("DequeUInt64") 
    .def("push_back" ,&DequeUInt64::push_back) 
    .def("push_front" ,&DequeUInt64::push_front); 

} 

Iは、上記のコードはstd=c++03gnu++03でなくc++11又はc++0xでコンパイルすることを観察しました。エラーは次のとおりです。

tmp.cpp: In function 'void init_module_tmp()': 
tmp.cpp:8:47: error: no matching function for call to 'boost::python::class_<std::deque<long unsigned int> >::def(const char [10], <unresolved overloaded function type>)' 
    .def("push_back" ,&DequeUInt64::push_back) 
              ^
In file included [from /opt/local/include/boost/python.hpp:18:0], [from tmp.cpp:2]: 
/opt/local/include/boost/python/class.hpp:223:11: 
    note: candidate: 
     template<class Derived> boost::python::class_<T, X1, X2, X3>::self& 
           boost::python::class_<T, X1, X2, X3>::def(const boost::python::def_visitor<Derived>&) 
           [with Derived = Derived; 
            W = std::deque<long unsigned int>; 
            X1 = boost::python::detail::not_specified; 
            X2 = boost::python::detail::not_specified; 
            X3 = boost::python::detail::not_specified] 
     self& def(def_visitor<Derived> const& visitor) 
    ^
    note: template argument deduction/substitution failed: 
tmp.cpp:8:47: 
    note: mismatched types 'const boost::python::def_visitor<U>' and 'const char [10]' 
      .def("push_back" ,&DequeUInt64::push_back) 
             ^
In file included [from /opt/local/include/boost/python.hpp:18:0], [from tmp.cpp:2]: 
/opt/local/include/boost/python/class.hpp:233:11: 
    note: candidate: 
     template<class F> boost::python::class_<T, X1, X2, X3>::self& 
         boost::python::class_<T, X1, X2, X3>::def(const char*, F) 
         [with F = F; 
           W = std::deque<long unsigned int>; 
           X1 = boost::python::detail::not_specified; 
           X2 = boost::python::detail::not_specified; 
           X3 = boost::python::detail::not_specified] 
    self& def(char const* name, F f) 
    ^
    note: template argument deduction/substitution failed: 
tmp.cpp:8:47: 
    note: couldn't deduce template parameter 'F' 
    .def("push_back" ,&DequeUInt64::push_back) 

私のブーストはboost: stable 1.60.0で、私のG ++はg++-mp-5 (MacPorts gcc5 5.4.0_0) 5.4.0です。どういうわけか、新しい標準が型/テンプレートの推論に問題を引き起こしていますが、正直なところ私はなぜそれほど理解できないのでしょうか? Boostは単にC++ 11でテストされていないため問題ですか?とにかく上記のエラーメッセージはどういう意味ですか?

+0

ただ、好奇心出し、クランは動作しますか? – refi64

+0

私は質問が2票しかないのに驚いています。タイトルの曖昧さを除けば、実際のMCVE、完全なコンパイラエラー、コンテキスト(Boostとコンパイラのバージョン)など、私が望むことができるすべてのものがあります。 – chris

答えて

8

エラーメッセージがあなたに手がかりを与えます。 referenceを見ると、あなたは、2つのオーバーロードがあります見ることができます:

void push_back(const T& value); 
void push_back(T&& value); // (since C++11) 

C++ 11の新しいオーバーロードを追加しました。したがって、これに対するポインタを引数として渡すことは無効になります。同様にpush_frontの場合。 C++ 11以前であっても、実装では独自のオーバーロードを追加できることに注意してください。

あなたは適切な型にキャストすることができます

.def("push_back" ,static_cast<void(DequeUInt64::*)(DequeUInt64::const_reference)>(&DequeUInt64::push_back)) 
.def("push_front" ,static_cast<void(DequeUInt64::*)(DequeUInt64::const_reference)>(&DequeUInt64::push_front)) 

を私はそれを唱えるのではなく、明示的にSTLのDon't Help the Compiler話ごとにテンプレート引数を指定します。あなたが最初の関数ポインタにそれを強制する場合

また、タナーさんのコメントにつき、ラムダを使用することができます。

.def("push_back" ,+[](DequeUInt64* d, DequeUInt64::const_reference x) { return d->push_back(x); }) 
.def("push_front" ,+[](DequeUInt64* d, DequeUInt64::const_reference x) { return d->push_front(x); }) 
+0

または見苦しいキャストの代わりにラムダを渡します。 – 0x499602D2

+0

@ 0x499602D2、私はちょうどそれを追加しようとしていました:) – chris

+0

'def()'はBoost.Pythonが署名を推論する方法を知らないのでlambdasを受け入れません。 '+'演算子を使ってそれを関数ポインタにキャストすることを考えてください(例えば '+ [](...){...}')。 ([デモ](http://coliru.stacked-crooked.com/a/b14d632428ed8881)) –

4

問題はC++ 11が移動セマンティクスすなわちvoid push_front(T&& value);

だからコンパイラは(<unresolved overloaded function type>)を選択するかを知っていないをサポートするために、push_backに過負荷を追加することです。あなたはこのように、それをスペルアウトする必要があります。

未解決のオーバーロードされた関数型のあなたはstd::deque::push_backに渡す

boost::python::class_<DequeUInt64>("DequeUInt64") 
.def<void (DequeUInt64::*)(const T&)>("push_back",&DequeUInt64::push_back) 
関連する問題