c++c++11stdbind

How to get std::bind refer the explicit constructor defined in class while providing pointer to class member function as arguement?


I'm using std::bind in my code as shown below:

std::bind(&Filter::odometryCallback, filter, std::placeholders::_1, odomTopicName, poseCallbackData,
                   twistCallbackData);

The Filter class has explicit constructors defined and hence no default constructors are generated by the compiler (for this class).

Now, the above line of code throws error with message "use of deleted function" and mentioning the copy constructor of Filter class.

My requirement:

How to get &Filter::odometryCallback to be considered/evaluated as pointer of explicitly constructed class instance member function ?

Any solutions and detailed explanation would be helpful.

Edit: Example code

I suppose, most of the code below doesn't make much sense to understand the context. But this is what I have right now.

OdomFunc setupOdometryCallback(std::string odomTopicName, EkfFilter& filter)
{
  using namespace RobotLocalization;
  std::vector<int> updateVec = filter.loadUpdateConfig(odomTopicName);
  std::vector<int> poseUpdateVec = updateVec;
  std::fill(poseUpdateVec.begin() + POSITION_V_OFFSET, poseUpdateVec.begin() + POSITION_V_OFFSET + TWIST_SIZE, 0);
  std::vector<int> twistUpdateVec = updateVec;
  std::fill(twistUpdateVec.begin() + POSITION_OFFSET, twistUpdateVec.begin() + POSITION_OFFSET + POSE_SIZE, 0);

  int poseUpdateSum = std::accumulate(poseUpdateVec.begin(), poseUpdateVec.end(), 0);
  int twistUpdateSum = std::accumulate(twistUpdateVec.begin(), twistUpdateVec.end(), 0);

  bool differential = false;
  bool relative = false;
  bool pose_use_child_frame = false;
  double poseMahalanobisThresh = std::numeric_limits<double>::max();
  double twistMahalanobisThresh = std::numeric_limits<double>::max();
  const CallbackData poseCallbackData(odomTopicName + "_pose", poseUpdateVec, poseUpdateSum, differential, relative,
                                      pose_use_child_frame, poseMahalanobisThresh);
  const CallbackData twistCallbackData(odomTopicName + "_twist", twistUpdateVec, twistUpdateSum, false, false, false,
                                       twistMahalanobisThresh);
  return std::bind(&EkfFilter::odometryCallback, filter, std::placeholders::_1, odomTopicName, poseCallbackData,
                   twistCallbackData);
}

Edit 2: I forgot to paste these code below previously.

The above Edit 1 & 2 code are in one .cpp file.

setupOdometryCallback(parameters) is a simple static function without any class.

using OdomFunc = std::function<void(const nav_msgs::Odometry::ConstPtr&)>;

int main(int argc, char** argv)
{
  ros::init(argc, argv, "ekf_node");

  ros::NodeHandle nh;
  ros::NodeHandle nh_priv("~");

  std::string odomTopicName = "/husky_velocity_controller/odom";

  EkfFilter ekf(nh, nh_priv);
  ekf.initialize();

  auto odomF = setupOdometryCallback(odomTopicName, ekf);
}

Solution

  • If you want to std::bind a reference parameter, you need to wrap it in std::reference_wrapper, as bind is an ordinary function, that does lvalue-to-rvalue conversion on it's arguments.

    std::bind(&Filter::odometryCallback, std::ref(filter), std::placeholders::_1, odomTopicName, poseCallbackData, twistCallbackData);