问题
I am using the boost::python
library in this tiny mwe.
#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 observed that the code above compiles with std=c++03
and gnu++03
but not with c++11
or c++0x
. The error is:
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)
My boost is boost: stable 1.60.0
and my g++ is g++-mp-5 (MacPorts gcc5 5.4.0_0) 5.4.0
. I can see that somehow the newer standard is causing problems with type/template inference but honestly I don't really understand why? Is the problem because Boost is simply not tested with c++11? What exactly does the error message above mean anyway?
回答1:
The error message gives you a clue:
unresolved overloaded function type
You pass in std::deque::push_back
. Looking at a reference, you can see there are two overloads:
void push_back( const T& value );
void push_back( T&& value ); // (since C++11)
C++11 added a new overload. Therefore, passing a pointer to this as an argument becomes invalid. Likewise for push_front
. Note that even before C++11, implementations are allowed to add their own overloads[citation needed].
You can cast it to the appropriate type:
.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))
I cast it rather than specify the template argument explicitly per STL's Don't Help the Compiler talk.
You can also use a lambda if you force it to a function pointer first, per Tanner's comment:
.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); })
回答2:
The problem is that C++11 added an overload to push_back
to support move semantics i.e. void push_front( T&& value );
So the compiler doesn't know which one to pick (<unresolved overloaded function type>
). You have to spell it out, like this:
boost::python::class_<DequeUInt64>("DequeUInt64")
.def<void (DequeUInt64::*)( const T&)>("push_back",&DequeUInt64::push_back)
来源:https://stackoverflow.com/questions/38536760/why-the-following-code-compiles-with-c03-but-not-with-c11