Suppose I have a callable type like so:
struct mutable_callable
{
int my_mutable = 0;
int operator()() { // Not const
return my_mutable++;
}
};
Note that mutable_callable
has a non-const operator()
that modifies a member variable.....
Now suppose I create a std::function
out of my type:
std::function<int()> foo = mutable_callable{};
Now I can do this:
void invoke(std::function<int()> const& z)
{
z();
}
int main()
{
invoke(foo); // foo changed.....oops
}
Now as far as I can tell std::function
s operator()
is const
as per:
https://en.cppreference.com/w/cpp/utility/functional/function/operator()
So my gut feeling is that you shouldn't be able to do this.....
But then looking at: https://en.cppreference.com/w/cpp/utility/functional/function/function
This doesn't seem to put any constraints on whether or not the callable type has a constant operator()
......
So my question is this: I am correct in assuming that std::function<int()> const&
is essentially the same thing as std::function<int()>&
that is there is no actually difference between the behavior of the two......and if that is the case why is it not const
correct?
By Alex Allain. The const keyword allows you to specify whether or not a variable is modifiable. You can use const to prevent modifications to variables and const pointers and const references prevent changing the data pointed to (or referenced).
A function becomes const when the const keyword is used in the function's declaration. The idea of const functions is not to allow them to modify the object on which they are called. It is recommended the practice to make as many functions const as possible so that accidental changes to objects are avoided.
const correctness can't improve performance because const_cast and mutable are in the language, and allow code to conformingly break the rules. This gets even worse in C++11, where your const data may e.g. be a pointer to a std::atomic , meaning the compiler has to respect changes made by other threads.
If the function is non-constant, then the function is allowed to change values of the object on which it is being called. So the compiler doesn't allow to create this chance and prevent you to call a non-constant function on a constant object, as constant object means you cannot change anything of it anymore.
This boils down to the same as struct A { int* x; };
, where in a const A a;
you can modify the value of *(a.x)
(but not where it points to). There is a level of indirection in std::function
(from the type erasure) through which const
is not propagated.
And no, std::function<int()> const& f
is not pointless. In a std::function<int()>& f
you would be able to assign a different functor to f
, which you cannot do in the const
case.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With