std :: function const正确性


11

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

struct mutable_callable
{
    int my_mutable = 0;
    int operator()() { // Not const
        return my_mutable++;
    }
};

请注意,它mutable_callable具有一个operator()用于修改成员变量的非常量。

现在假设我创建了一个std::function我的类型之外的代码:

std::function<int()> foo = mutable_callable{};

现在我可以这样做:

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

int main()
{
    invoke(foo); // foo changed.....oops
}

现在,据我所知,std::functions operator()的信息const如下:https : //en.cppreference.com/w/cpp/utility/functional/function/operator()

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

但随后查看:https : //en.cppreference.com/w/cpp/utility/functional/function/function

这似乎对可调用类型是否具有常量没有任何限制operator()……

所以我的问题是:我认为这std::function<int()> const&与本质上是同一件事是正确的,std::function<int()>&两者之间的行为实际上没有区别……如果是这样,那为什么不const正确呢?


@MaxLanghof号.... std::function等价struct a{ std::any x; };于....
DarthRubik,

这是MSVC std::function实现内部的一小段代码:i.stack.imgur.com/eNenN.png其中using _Ptrt = _Func_base<_Ret, _Types...>。我休息一下
Max Langhof

Answers:


3

这归结为一样struct A { int* x; };,在这里const A a;,你可以修改的值*(a.x)(但不是它指向的)。std::function(从类型擦除开始)存在一个间接级别,该级别const不传播。

不,std::function<int()> const& f不是没有意义的。在中,std::function<int()>& f您可以为分配一个不同的函子f,而在这种const情况下则不能这样做。


是的.....这实际上很有意义.....尽管乍一看仍然令人困惑
DarthRubik

我相信这是设计缺陷。这种间接性应该是对用户透明的实现细节,并且可以使用一些元编程来传播常量。
伊戈尔·

@IgorR。是的,可以传播常数。std::vector这样做,std::unique_ptr不是。我觉得std::function并不是真的要表达函子状态的不变性。也许我们可以重新利用可恶的函数类型(例如std::function<int() const>)来区分?
Max Langhof

unique_ptr不应该传播常量,因为常规指针不能。而且std::function<int() const>不会编译。
Igor R.

@IgorR。我知道。我的观点是,标准库的某些部分可以执行此操作,而其他部分则不可以。std::function我不清楚应该属于哪一类。并且这std::function<int() const>是一个假设-当然它现在不会编译,但是如果可以使OP有效,它将满足例如此处的OP,并表示“只能分配具有operator() const(或无状态)函子的函子”吗?(即使在幕后,由于使用了令人讨厌的函数类型,这也会非常残酷)?
Max Langhof
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.