std::bind and std::function with polymorphism, base class
std::bind and std::function with polymorphism, base class
我正在尝试将一个对象绑定到一个函数,但是正在调用基础的 class 函数。
该代码只是真实代码的示例。
我只会在后面的真实代码中得到字符串。
class A {
public:
virtual void f(const std::string &s) {
std::cout << "A " << s << std::endl;
}
};
class B : public A {
public:
void f(const std::string &s) override {
std::cout << "B " << s << std::endl;
}
};
void main() {
std::unique_ptr<A> a = std::make_unique<B>();
std::function<void(const std::string &)> callback
= std::bind(&A::f, *a, std::placeholders::_1);
callback("my string");
}
结果是
A my string
我尝试将其更改为 &B:f,但出现错误。
No viable conversion from 'typename _Bind_helper<__is_socketlike<void (B::*)(const basic_string<char> &)>::value, void (B::*)(const basic_string<char> &), A &, const _Placeholder<1> &>::type' (aka '_Bind<void (Centerity::Cluster::Correlation::B::*(Centerity::Cluster::Correlation::A, std::_Placeholder<1>))(const std::basic_string<char> &)>') to 'std::function<void (const std::string &)>' (aka 'function<void (const basic_string<char> &)>')
我尝试将其更改为 A* a = B();
相同的结果。
在任何地方都找不到类似的代码。
当然,创建 B b
会调用 B::f
,但这对我没有帮助。
我可以失去绑定并使用 lambda,但我不知道如何。
注意:
我不知道你用的是哪个编译器,但main不应该是空的。我已在下面的代码中修复它:
#include <memory>
#include <iostream>
#include <functional>
class A {
public:
virtual void f(const std::string &s)
{
std::cout << "A " << s << std::endl;
}
};
class B: public A {
public:
void f(const std::string &s) override
{
std::cout << "B " << s << std::endl;
}
};
int main()
{
std::unique_ptr<A> a = std::make_unique<B>();
auto callback = std::bind(&A::f, a.get(), std::placeholders::_1);
callback("my string");
return 0;
}
输出:
B my string
要点是将指向基 class 的指针(指向派生 class 的对象)传递给 std::bind(&A::f, a.get(), std::placeholders::_1);
。
如果你按值传递,那么你的基础 class A 的一个新对象将被创建(通过复制构造函数)并且基础 class 的 f 版本将被调用,正如你所观察到的在你的程序中。
如您要求 lambda 版本:
class A {
public:
virtual void f(const std::string &s) {
std::cout << "A " << s << std::endl;
}
};
class B : public A {
public:
void f(const std::string &s) override {
std::cout << "B " << s << std::endl;
}
};
int main() {
std::unique_ptr<A> a = std::make_unique<B>();
auto callback = [&a](const std::string& s){ return a->f(s); };
callback("my string");
}
我正在尝试将一个对象绑定到一个函数,但是正在调用基础的 class 函数。 该代码只是真实代码的示例。 我只会在后面的真实代码中得到字符串。
class A {
public:
virtual void f(const std::string &s) {
std::cout << "A " << s << std::endl;
}
};
class B : public A {
public:
void f(const std::string &s) override {
std::cout << "B " << s << std::endl;
}
};
void main() {
std::unique_ptr<A> a = std::make_unique<B>();
std::function<void(const std::string &)> callback
= std::bind(&A::f, *a, std::placeholders::_1);
callback("my string");
}
结果是
A my string
我尝试将其更改为 &B:f,但出现错误。
No viable conversion from 'typename _Bind_helper<__is_socketlike<void (B::*)(const basic_string<char> &)>::value, void (B::*)(const basic_string<char> &), A &, const _Placeholder<1> &>::type' (aka '_Bind<void (Centerity::Cluster::Correlation::B::*(Centerity::Cluster::Correlation::A, std::_Placeholder<1>))(const std::basic_string<char> &)>') to 'std::function<void (const std::string &)>' (aka 'function<void (const basic_string<char> &)>')
我尝试将其更改为 A* a = B();
相同的结果。
在任何地方都找不到类似的代码。
当然,创建 B b
会调用 B::f
,但这对我没有帮助。
我可以失去绑定并使用 lambda,但我不知道如何。
注意:
我不知道你用的是哪个编译器,但main不应该是空的。我已在下面的代码中修复它:
#include <memory>
#include <iostream>
#include <functional>
class A {
public:
virtual void f(const std::string &s)
{
std::cout << "A " << s << std::endl;
}
};
class B: public A {
public:
void f(const std::string &s) override
{
std::cout << "B " << s << std::endl;
}
};
int main()
{
std::unique_ptr<A> a = std::make_unique<B>();
auto callback = std::bind(&A::f, a.get(), std::placeholders::_1);
callback("my string");
return 0;
}
输出:
B my string
要点是将指向基 class 的指针(指向派生 class 的对象)传递给 std::bind(&A::f, a.get(), std::placeholders::_1);
。
如果你按值传递,那么你的基础 class A 的一个新对象将被创建(通过复制构造函数)并且基础 class 的 f 版本将被调用,正如你所观察到的在你的程序中。
如您要求 lambda 版本:
class A {
public:
virtual void f(const std::string &s) {
std::cout << "A " << s << std::endl;
}
};
class B : public A {
public:
void f(const std::string &s) override {
std::cout << "B " << s << std::endl;
}
};
int main() {
std::unique_ptr<A> a = std::make_unique<B>();
auto callback = [&a](const std::string& s){ return a->f(s); };
callback("my string");
}