Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does C++ allow std::function assignments to imply an object copy?

My question concerns the line of code below marked with the // WHY??? comment.

Below is a toy example of some code I was expecting to break: a std::function variable is assigned a function pointer whose parameters almost match, but differ in const and &. It didn't break. I've figured out why it works -- there's a copy constructor call added by the compiler that I didn't expect.

My question is: why does C++ allow this case? What is the use-case that made the C++ committee decide this should work (as opposed to the compiler rejecting this assignment)?

#include <memory>
#include <functional>
#include <iostream>

class Thing {
  public:
    Thing(int count) : count_(count) {}
    int count_;
};

typedef std::function<void(const Thing&)> ConstByRefFunction;

void DoThingByValue(Thing event) { event.count_ += 5; }

int main() {
  Thing thing(95);
  ConstByRefFunction func = DoThingByValue; // WHY???
  // The following line copies thing even though anyone looking at
  // the signature of ConstByRefFunction would expect it not to copy.
  func(thing);
  std::cout << thing.count_ << std::endl; // still 95
  return 0;
}
like image 648
srm Avatar asked Oct 19 '25 19:10

srm


1 Answers

The signature you specify in the std::function template is the signature used for the std::function's operator() overload, NOT the signature used for the target that the operator() calls.

You can assign any target to std::function which is Callable using the parameters of the operator(). In your example, DoThingByValue() is an acceptable target because a const Thing& parameter can be passed by value to a Thing parameter (thus invoking the Thing copy constructor), no different than if you were doing something like this:

void DoThingByValue(Thing event) {
  ...
}

void DoThingByConstRef(const Thing &event) {
  DoThingByValue(event); // <-- COPY HERE
}
like image 190
Remy Lebeau Avatar answered Oct 22 '25 11:10

Remy Lebeau



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!