gpt4 book ai didi

c++ - 将函数对象分配给函数包装器后出现意外行为

转载 作者:行者123 更新时间:2023-12-02 07:35:31 26 4
gpt4 key购买 nike

我正在搜索应用程序中的一个错误,我最终修复了该错误,但并不完全理解。可以使用以下简单程序重现该行为:

#include <iostream>
#include <memory>
#include <functional>

struct Foo
{
virtual int operator()(void) { return 1; }
};

struct Bar : public Foo
{
virtual int operator()(void) override { return 2; }
};

int main()
{
std::shared_ptr<Foo> p = std::make_shared<Bar>();
std::cout << (*p)() << std::endl;

std::function<int(void)> f;
f = *p;
std::cout << f() << std::endl;

return 0;
}

该行的输出

std::cout << (*p)() << std::endl;

2,这当然正如我所料。

但是该行的输出

std::cout << f() << std::endl;

1。这让我很惊讶。我什至感到惊讶的是,允许赋值 f = *p 并且不会导致错误。

我不要求解决方法,因为我通过 lambda 修复了它。
我的问题是,当我执行 f = *p 时发生了什么,为什么输出是 1 而不是 2

我已使用 gcc (MinGW) 和 Visual Studio 2019 重现了该问题。
此外我想提一下输出

Bar b;
std::function<int(void)> f1 = b;
std::cout << f1() << std::endl;

又是2

最佳答案

对象切片发生在这里。

给出点f = *p; , p类型为std::shared_ptr<Foo> ,那么 *p 的类型是 Foo& (而不是 Bar& )。甚至是assignment operator of std::function 通过引用获取参数,但是

4) Sets the target of *this to the callable f, as if by executing function(std::forward<F>(f)).swap(*this);.

请注意 F上面推导为Foo&也。还有constructor of std::function 按值获取参数,发生对象切片,效果变为 fFoo 类型的对象分配这是从 *p 切片复制的.

template< class F > 
function( F f );

关于c++ - 将函数对象分配给函数包装器后出现意外行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57724907/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com