【问题标题】:std::function const correctnessstd::function const 正确性
【发布时间】:2020-03-29 10:46:42
【问题描述】:

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

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&lt;int()&gt; const&amp;std::function&lt;int()&gt;&amp; 本质上是一样的,这是正确的,即两者的行为之间实际上没有区别......如果那是这个案子为什么const不正确?

【问题讨论】:

  • @MaxLanghof No.....std::function 里面有一个 struct a{ std::any x; }; 等价物.....
  • 这是 MSVC std::function 实现内部的一个小 sn-p:i.stack.imgur.com/eNenN.png 其中using _Ptrt = _Func_base&lt;_Ret, _Types...&gt;。我休息一下。

标签: c++ std-function const-correctness


【解决方案1】:

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

不,std::function&lt;int()&gt; const&amp; f 并非毫无意义。在std::function&lt;int()&gt;&amp; f 中,您可以为f 分配不同的函子,而在const 情况下则无法做到这一点。

【讨论】:

  • 是的......这实际上很有意义......但乍一看仍然令人困惑
  • 我认为这是一个设计缺陷。这种间接性应该是对用户透明的实现细节,并且可以使用一些元编程来传播常量。
  • @IgorR。是的,常数可以传播。 std::vector 会这样做,std::unique_ptr 不会。我觉得std::function 并不是真的要表达函子状态的不变量。也许我们可以重新利用可恶的函数类型(即std::function&lt;int() const&gt;)来区分?
  • unique_ptr 不应传播常量,因为常规指针不会。并且std::function&lt;int() const&gt; 不会编译。
  • @IgorR。我知道。我的观点是标准库的某些部分会这样做,而其他部分则不会。我不清楚std::function 应该属于哪个类别。 std::function&lt;int() const&gt; 是一个假设 - 当然它现在不能编译,但它会满足例如如果可以使此处的OP有效,则表示“只能分配具有operator() const(或无状态的)的函子”? (即使在幕后,由于使用了可恶的函数类型,这将是相当残暴的)?
猜你喜欢
  • 1970-01-01
  • 2022-01-10
  • 2022-08-04
  • 2011-05-06
  • 2023-04-08
  • 1970-01-01
  • 1970-01-01
  • 2021-07-12
  • 2018-03-06
相关资源
最近更新 更多