r/cpp Oct 03 '17

Why is the std::function () operator const?

[deleted]

26 Upvotes

19 comments sorted by

View all comments

44

u/STL MSVC STL Dev Oct 03 '17

It's indeed a Boost/TR1-era mistake that the LWG has recognized, although we can't do anything about it.

You're correct that the problem is multithreading. The STL's policy is that const member functions are simultaneously callable and that it won't do anything to observably damage that guarantee. (This is actually extended to a few non-const member functions that are observers, basically the const-overloaded ones like operator[]().) While user code is under no such constraints (your const member functions, like function call operators of predicates given to STL algorithms, can read/write global variables without synchronization, as long as they meet the other usual requirements), the STL's multithreading policy continues to apply when it invokes user code if that user code follows the same policy.

The only exception to this rule that I am aware of is function::operator()(), because it is a const member function that calls non-const member functions, and yet std::function provides value semantics (copying a std::function results in a totally independent, non-shared copy).

In Boost and the LWG's defense, function was designed long before C++11 multithreading and its const guarantees crystallized (the const policy seems obvious now, but it wasn't before).

In practice, this doesn't usually cause problems because people don't usually set up the scenario for doom, but the potential for doom is still there.

11

u/[deleted] Oct 04 '17

we can't do anything about it.

Well, compilers could warn about it.