9

Consider the following example:

#include <iostream>
#include <functional>

struct A
{
    int i;
    void operator()() 
    {
        std::cout << ++i;
    }
};

void test(std::function<void()> const& fun)
{
    fun();
}

int main() {
    const std::function<void()> f{A{}};
    test(f);
    test(f);
}

Here, a const std::function is able to call a non-const operator().

Output:

12

The same happens if I supply a mutable lambda e.g. test([x = 0]() mutable { ++x; });

How can that be?

Is it normal that a const std::function may wrap a mutable functor?

rustyx
  • 80,671
  • 25
  • 200
  • 267

1 Answers1

12

Is it normal that a const std::function may wrap a mutable functor?

Unfortunately, yes. std::function::operator() is unconditionally qualified as const and doesn't care whether or not the wrapped Callable is mutated. Some papers attempted to tackle this issue, but AFAIK nothing concrete was yet decided:

Vittorio Romeo
  • 90,666
  • 33
  • 258
  • 416