引用作为类成员的函数
Refer to a function that is member of a class
所以我有这个意大利面条代码项目,我正在尝试使它面向对象。可怜的是,我遇到了我不太理解的错误,所以我尝试创建简单的代码,这些代码确实会抛出相同的错误,而事实并非如此。
所以这里有一些编译的简约代码:
(文件名为"ims.cpp"(
#include <cstdio>
#include <ros/ros.h>
#include <visualization_msgs/Marker.h>
#include <visualization_msgs/InteractiveMarker.h>
#include <interactive_markers/interactive_marker_server.h>
#include <interactive_markers/menu_handler.h>
#include <rosbag/bag.h>
#include <rosbag/view.h>
#include <ros/param.h>
#include <fstream>
#include <cmath>
#include <boost/algorithm/string/split.hpp>
#include <boost/algorithm/string.hpp>
using namespace visualization_msgs;
using namespace geometry_msgs;
using namespace std;
using namespace boost;
boost::shared_ptr<interactive_markers::InteractiveMarkerServer> server;
void doNothing(const InteractiveMarkerFeedbackConstPtr &feedback){
}
void testServer(){
InteractiveMarker inter_marker;
inter_marker.header.frame_id = 1;
Point pos;
pos.x = 3;
pos.y = 3;
inter_marker.pose.position = pos;
inter_marker.scale = 2;
inter_marker.name = "testServer";
server->insert(inter_marker, &doNothing);
}
int main(){}
解释:这是一个ROS(机器人操作系统(项目,我仍然相信这是一个一般的C ++问题,所以我没有在他们的"ros::answers"论坛中提出这个问题。请不要被类型混淆,我们会解决问题。
函数"interactive_markers::InteractiveMarkerServer.insert"需要一个"visualization_msgs::InteractiveMarker &"和一个参数类型为"InteractiveMarkerFeedbackConstPtr &"的函数。 请参阅: http://docs.ros.org/jade/api/interactive_markers/html/classinteractive__markers_1_1InteractiveMarkerServer.html
因此,抛出我的错误的最小代码将是"doNothing"函数中根本没有所需参数的代码,如下所示:
(文件名为"ims.cpp"(
#include <as above>
using namespace visualization_msgs;
using namespace geometry_msgs;
using namespace std;
using namespace boost;
boost::shared_ptr<interactive_markers::InteractiveMarkerServer> server;
void doNothing(){
}
void testServer(){
InteractiveMarker inter_marker;
inter_marker.header.frame_id = 1;
Point pos;
pos.x = 3;
pos.y = 3;
inter_marker.pose.position = pos;
inter_marker.scale = 2;
inter_marker.name = "testServer";
server->insert(inter_marker, &doNothing);
}
int main(){}
抛出错误:
In file included from /usr/include/boost/function/detail/maybe_include.hpp:18:0,
from /usr/include/boost/function/detail/function_iterate.hpp:14,
from /usr/include/boost/preprocessor/iteration/detail/iter/forward1.hpp:52,
from /usr/include/boost/function.hpp:64,
from /opt/ros/indigo/include/ros/forwards.h:40,
from /opt/ros/indigo/include/ros/common.h:37,
from /opt/ros/indigo/include/ros/ros.h:43,
from /home/ros/ros/src/robotrainer_editor/heika_beta/ims/src/ims.cpp:3:
/usr/include/boost/function/function_template.hpp: In instantiation of ‘static void boost::detail::function::void_function_invoker1<FunctionPtr, R, T0>::invoke(boost::detail::function::function_buffer&, T0) [with FunctionPtr = void (*)(); R = void; T0 = const boost::shared_ptr<const visualization_msgs::InteractiveMarkerFeedback_<std::allocator<void> > >&]’:
/usr/include/boost/function/function_template.hpp:934:38: required from ‘void boost::function1<R, T1>::assign_to(Functor) [with Functor = void (*)(); R = void; T0 = const boost::shared_ptr<const visualization_msgs::InteractiveMarkerFeedback_<std::allocator<void> > >&]’
/usr/include/boost/function/function_template.hpp:722:7: required from ‘boost::function1<R, T1>::function1(Functor, typename boost::enable_if_c<boost::type_traits::ice_not<boost::is_integral<Functor>::value>::value, int>::type) [with Functor = void (*)(); R = void; T0 = const boost::shared_ptr<const visualization_msgs::InteractiveMarkerFeedback_<std::allocator<void> > >&; typename boost::enable_if_c<boost::type_traits::ice_not<boost::is_integral<Functor>::value>::value, int>::type = int]’
/usr/include/boost/function/function_template.hpp:1069:16: required from ‘boost::function<R(T0)>::function(Functor, typename boost::enable_if_c<boost::type_traits::ice_not<boost::is_integral<Functor>::value>::value, int>::type) [with Functor = void (*)(); R = void; T0 = const boost::shared_ptr<const visualization_msgs::InteractiveMarkerFeedback_<std::allocator<void> > >&; typename boost::enable_if_c<boost::type_traits::ice_not<boost::is_integral<Functor>::value>::value, int>::type = int]’
/home/ros/ros/src/robotrainer_editor/heika_beta/ims/src/ims.cpp:40:42: required from here
/usr/include/boost/function/function_template.hpp:112:11: error: too many arguments to function
BOOST_FUNCTION_RETURN(f(BOOST_FUNCTION_ARGS));
这是有道理的,对吧?该函数没有所需的参数,因此编译器会抱怨。
所以现在我们到了真正的问题:在面向对象的代码中,我有同样的问题:
头文件
(文件名为"ims.h"(
#include <cstdio>
#include <ros/ros.h>
#include <visualization_msgs/Marker.h>
#include <visualization_msgs/InteractiveMarker.h>
#include <interactive_markers/interactive_marker_server.h>
#include <interactive_markers/menu_handler.h>
#include <rosbag/bag.h>
#include <rosbag/view.h>
#include <ros/param.h>
#include <fstream>
#include <cmath>
#include <boost/algorithm/string/split.hpp>
#include <boost/algorithm/string.hpp>
using namespace visualization_msgs;
using namespace geometry_msgs;
using namespace std;
using namespace boost;
class IMS{
boost::shared_ptr<interactive_markers::InteractiveMarkerServer> server;
IMS();
void doNothing(const InteractiveMarkerFeedbackConstPtr &feedback);
void testServer();
int main();
};
CPP声明
(文件名为"ims.cpp"(
#include <ims.h>
IMS::IMS(){}
void IMS::doNothing(const InteractiveMarkerFeedbackConstPtr &feedback){
}
void IMS::testServer(){
InteractiveMarker inter_marker;
inter_marker.header.frame_id = 1;
Point pos;
pos.x = 3;
pos.y = 3;
inter_marker.pose.position = pos;
inter_marker.scale = 2;
inter_marker.name = "testServer";
server->insert(inter_marker, &IMS::doNothing); //other options that didn't work either: doNothing);//*this->doNothing(const InteractiveMarkerFeedbackConstPtr &feedback));//*this->doNothing());//this->doNothing);//&this->doNothing);//&IMS::doNothing);//&doNothing);
}
int IMS::main(){}
抛出错误:
In file included from /usr/include/boost/function/detail/maybe_include.hpp:18:0,
from /usr/include/boost/function/detail/function_iterate.hpp:14,
from /usr/include/boost/preprocessor/iteration/detail/iter/forward1.hpp:52,
from /usr/include/boost/function.hpp:64,
from /opt/ros/indigo/include/ros/forwards.h:40,
from /opt/ros/indigo/include/ros/common.h:37,
from /opt/ros/indigo/include/ros/ros.h:43,
from /home/ros/ros/src/robotrainer_editor/heika_beta/ims/include/ims.h:3,
from /home/ros/ros/src/robotrainer_editor/heika_beta/ims/src/ims.cpp:1:
/usr/include/boost/function/function_template.hpp: In instantiation of ‘static void boost::detail::function::function_void_mem_invoker1<MemberPtr, R, T0>::invoke(boost::detail::function::function_buffer&, T0) [with MemberPtr = void (IMS::*)(const boost::shared_ptr<const visualization_msgs::InteractiveMarkerFeedback_<std::allocator<void> > >&); R = void; T0 = const boost::shared_ptr<const visualization_msgs::InteractiveMarkerFeedback_<std::allocator<void> > >&]’:
/usr/include/boost/function/function_template.hpp:934:38: required from ‘void boost::function1<R, T1>::assign_to(Functor) [with Functor = void (IMS::*)(const boost::shared_ptr<const visualization_msgs::InteractiveMarkerFeedback_<std::allocator<void> > >&); R = void; T0 = const boost::shared_ptr<const visualization_msgs::InteractiveMarkerFeedback_<std::allocator<void> > >&]’
/usr/include/boost/function/function_template.hpp:722:7: required from ‘boost::function1<R, T1>::function1(Functor, typename boost::enable_if_c<boost::type_traits::ice_not<boost::is_integral<Functor>::value>::value, int>::type) [with Functor = void (IMS::*)(const boost::shared_ptr<const visualization_msgs::InteractiveMarkerFeedback_<std::allocator<void> > >&); R = void; T0 = const boost::shared_ptr<const visualization_msgs::InteractiveMarkerFeedback_<std::allocator<void> > >&; typename boost::enable_if_c<boost::type_traits::ice_not<boost::is_integral<Functor>::value>::value, int>::type = int]’
/usr/include/boost/function/function_template.hpp:1069:16: required from ‘boost::function<R(T0)>::function(Functor, typename boost::enable_if_c<boost::type_traits::ice_not<boost::is_integral<Functor>::value>::value, int>::type) [with Functor = void (IMS::*)(const boost::shared_ptr<const visualization_msgs::InteractiveMarkerFeedback_<std::allocator<void> > >&); R = void; T0 = const boost::shared_ptr<const visualization_msgs::InteractiveMarkerFeedback_<std::allocator<void> > >&; typename boost::enable_if_c<boost::type_traits::ice_not<boost::is_integral<Functor>::value>::value, int>::type = int]’
/home/ros/ros/src/robotrainer_editor/heika_beta/ims/src/ims.cpp:19:47: required from here
/usr/include/boost/function/function_template.hpp:225:11: error: no match for call to ‘(boost::_mfi::mf1<void, IMS, const boost::shared_ptr<const visualization_msgs::InteractiveMarkerFeedback_<std::allocator<void> > >&>) (const boost::shared_ptr<const visualization_msgs::InteractiveMarkerFeedback_<std::allocator<void> > >&)’
BOOST_FUNCTION_RETURN(boost::mem_fn(*f)(BOOST_FUNCTION_ARGS));
诊断:
我的一个朋友实际上已经诊断出问题的合理来源:编译器将代码重新格式化为这个
void IMS::doNothing(IMS this, const InteractiveMarkerFeedbackConstPtr &feedback){
这当然会导致错误,因为该参数不再符合我们的期望。
所以我的要求是:
这个诊断正确吗?
如果是:是否可以解决方法以及如何解决方法?
否则:实际问题是什么?
感谢任何甚至完全阅读这个长线程的人,并提前感谢您的回答!
解决方案(遵循"einpoklum"的建议(
最适合我的概念的解决方案是lambda,创建一个函数来包装恶意的"this"参数。
标准::函数无 = [这](const InteractiveMarkerFeedbackConstPtr &feedback({this->doNothing(feedback(;};
服务器>插入(inter_marker,什么都没有(;
谢谢你和所有非常费心阅读整个线程的人,很抱歉我很难理解地提出这个问题。
试图穿过堆积如山的文本并冒险回答:我认为(但不确定(问题是你试图传递一个(非静态(成员函数,就好像它是一个独立的函数一样。
这应该行不通,因为你不能"像那样"调用成员函数 - 它必须有一个关联的对象。在实现级别,需要使用该类实例的地址调用该代码段,以用作this
对象。
在这些情况下,您可以做的是:
- 使用
std::mem_fn
包装成员函数以获得正确的函数,其中额外的第一个参数是实例,或者 - 使用以某种方式实例化对象(或仅将实例作为引用(并调用该实例的方法的 lambda。lambda 本身将退化为一个独立的函数,您可以传递其指针。
- 使该方法
static
- 如果它实际上不使用任何特定于实例的数据。
- 如何使用指针传递给函数的数组中对象的函数成员
- c++构造函数成员初始化:传递参数
- 创建 std::函数,它返回具有函数成员值的变量.分段错误
- 如何在C++通过公共函数访问私有函数成员?
- 解释了构造函数成员初始化列表
- 调用std::函数成员时内存损坏
- 是否可以为模板类的模板函数成员设置别名?
- 捕获 lambda 函数C++成员变量
- 构造函数成员初始值设定项跨成员列出,安全吗?
- 获取与在模板参数中传递的函数成员类型相同的类
- 如何从公共函数成员访问地图私有成员
- C 构造函数成员分配优化
- 使用命名空间进行函数成员定义
- 函数成员作为 CUDA 内核的参数
- 模板基类函数成员的别名
- 函数成员中用于void和继承的enable_if
- 头文件中是否定义了一个很长的Class函数成员
- 类内/构造函数成员初始化
- 使用指向部分专用函数成员的指针自动填充向量
- 指向函数成员的指针