Я искал ошибку в приложении, которую я наконец исправил, но не совсем понял. Поведение может быть воспроизведено с помощью следующей простой программы:
#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
разрешено и не вызывает ошибку.
Я не прошу обходной путь, потому что я установил его с помощью лямбды.
У меня вопрос: что происходит, когда я делаю f = *p
и почему вывод 1
, а не 2
?
Я воспроизвел проблему с помощью gcc (MinGW) и Visual Studio 2019.
Далее я хочу упомянуть, что вывод
Bar b;
std::function<int(void)> f1 = b;
std::cout << f1() << std::endl;
снова 2
.