DarthRubik
DarthRubik

Reputation: 3985

std::function const correctness

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::functions 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?

Upvotes: 11

Views: 703

Answers (1)

Max Langhof
Max Langhof

Reputation: 23701

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.

Upvotes: 4

Related Questions