C++ 函数常量正确性

C++ 函数常量正确性,c++,std-function,const-correctness,C++,Std Function,Const Correctness,假设我有这样一个可调用类型: struct mutable_callable { int my_mutable = 0; int operator()() { // Not const return my_mutable++; } }; 请注意,mutable\u callable有一个非常量运算符(),用于修改成员变量 现在假设我用我的类型创建了一个std::function: std::function<int()> foo = muta

假设我有这样一个可调用类型:

struct mutable_callable
{
    int my_mutable = 0;
    int operator()() { // Not const
        return my_mutable++;
    }
};
请注意,
mutable\u callable
有一个非常量
运算符()
,用于修改成员变量

现在假设我用我的类型创建了一个
std::function

std::function<int()> foo = mutable_callable{};
std::function foo=mutable_callable{};
现在我可以做到:

void invoke(std::function<int()> const& z)
{
    z();
}

int main()
{
    invoke(foo); // foo changed.....oops
}
void调用(std::function const&z)
{
z();
}
int main()
{
调用(foo);//foo已更改…..oops
}
现在据我所知,
std::function
s
operator()
const
根据:

所以我的直觉是你不应该这样做

但再看看:

这似乎没有对可调用类型是否具有常量
操作符()


所以我的问题是:我正确地假设
std::function const&
std::function&
本质上是相同的,即两者的行为实际上没有区别……如果是这样,为什么它不
const
正确?

这可以归结为与
结构A相同{int*x;};
,其中在
常量a;
中,您可以修改
*(a.x)
的值(但不是它指向的位置)。在
std::function
(从类型擦除)中有一个间接级别,通过该级别
常量
不会传播


不,
std::function const&f
并不是毫无意义的。在
std::function&f
中,您可以将不同的函子分配给
f
,这在
const
情况下是无法做到的。

@MaxLanghof no.…
std::function
结构a{std::any x;}
在它里面…..这里是MSVC
std::function
实现内部的一个小片段:where
使用Ptrt=Funcu base
。我的情况就到此为止了。是的…..这实际上很有意义…..乍看起来仍然让人困惑,虽然我认为这是一个设计缺陷。这个间接应该是一个实现细节对用户来说不是,常量可以通过一些元编程来传播。@IgorR。是的,常量可以传播。
std::vector
做到了这一点,
std::unique\u ptr
没有。我觉得
std::function
实际上并不是要表达functor状态的不变量。也许我们可以重新利用讨厌的fu操作类型(即
std::function
)要区分?
unique\u ptr
不应该像常规指针那样传播常量。而且
std::function
不会编译。@IgorR.我知道。我的观点是标准库的某些部分会这样做,而另一些部分不会。我不清楚
std::function
应该属于哪一类。而且
std::函数
是一个假设——当然它现在没有编译,但是如果它可以有效,它会满足这里的OP吗,表示“只能分配带有
运算符()常量的函子(或无状态的函子)”?(即使在幕后,由于使用了令人讨厌的函数类型,这会非常糟糕)?