std::function const correctness not followed

  • A+

I was surprised to find this code compiles:

#include <functional>  struct Callable {     void operator() () { count++; }     void operator() () const = delete;     int count = 0; };  int main() {     const Callable counter;     // counter(); //error: use of deleted function 'void Callable::operator()() const'     std::function<void(void)> f = counter;     f();      const auto cf = f;     cf();  }

This will call the non-const call operator of Callable. Comparatively, if you do const auto cf = counter; cf(); then it errors out as expected. So, why does const correctness not seem to be followed with std::function?


std::function adds a layer of indirection, and this layer of indirection does not pass through constness to the callable.

I'm not really sure why this is — probably because std::function takes a copy of the callable and has no need to keep the copy const (in fact this might break assignment semantics) — I'm also not really sure why you'd need it to.

(Of course, directly invoking operator() on an object of a type that you just so happened to call Callable and declared as const will require a const context, as it would with any other object.)

Best practice is to give the callable a const operator() and leave it at that.

tl;dr: true, but not a bug, and doesn't matter


:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: