为什么以下代码使用`c ++ 03`而不是`c ++ 11`进行编译 [英] Why the following code compiles with `c++03` but not with `c++11`

查看:115
本文介绍了为什么以下代码使用`c ++ 03`而不是`c ++ 11`进行编译的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在这个很小的mwe中使用boost::python库.

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);

} 

我观察到上面的代码是用std=c++03gnu++03编译的,而不是用c++11c++0x编译的.错误是:

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)

我的助推力是boost: stable 1.60.0,我的g ++是g++-mp-5 (MacPorts gcc5 5.4.0_0) 5.4.0.我可以看到,较新的标准以某种方式导致类型/模板推断出现问题,但老实说,我真的不明白为什么?是因为Boost根本没有在c ++ 11上进行测试而引起的问题吗?上面的错误消息到底是什么意思?

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?

推荐答案

错误消息为您提供了一个线索:

The error message gives you a clue:

无法解析的重载函数类型

unresolved overloaded function type

您传入了std::deque::push_back.查看引用,您会看到两个重载:

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添加了新的重载.因此,将指向它的指针作为参数传递将变得无效.对于push_front也是如此.请注意,即使在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))

我强制转换它,而不是根据STL的不帮助编译器明确指定模板参数谈话.

I cast it rather than specify the template argument explicitly per STL's Don't Help the Compiler talk.

根据Tanner的评论,如果先将lambda强制设置为函数指针,则也可以使用该参数:

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); })

这篇关于为什么以下代码使用`c ++ 03`而不是`c ++ 11`进行编译的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆