绑定派生类方法C++从实例范围之外的分隔 std::function 变量调用
Binding derived class method in C++ to be called from separated std::function variable, outside the scope of the instance
考虑拥有一个由多个子类继承的基类。
是否可以绑定它的一些方法来创建可以直接调用而不是从继承的类实例调用的函数。
以下示例应强调这种情况:
class A {
virtual void method(int a, int b) { ... }
};
class B : public A {
virtual void method(int a, int b) { ... }
};
class C : public A {
virtual void method(int a, int b) { ... }
};
void main () {
A * a = new B();
A * aa= new C();
std::function<void(int,int)> f1 = std::bind(&A::method, &a);
std::function<void(int,int)> f2 = std::bind(&A::method, &aa);
f(1,2);
f(2,3);
...
}
但是,由于以下错误,它无法编译:
No viable conversion from '__bind<void (A::*)(int, int), A **>' to 'std::function<void (int, int)>'
也许任何人都可以帮我修复它?
您需要为参数使用占位符。我还会从第二个参数中删除引用,因为您已经有一个指针,并且传递对指针的引用将传入指针的地址,这不是您想要的。
std::function<void(int,int)> f1 = std::bind(&A::method, a, std::placeholders::_1, std::placeholders::_2);
希望这有帮助。
您的代码存在一些问题。
- 您需要公开这些方法
void main()
来自预标准化的时代,但它在代码C++无效。你需要int main()
- 不要使用具有所有权的原始指针。 使用智能指针。
- 不要使用
std::bind
.使用λ。他们在各个方面都更胜一筹。
为了不让所有更改使你过载,让我们使用 lambda 执行此操作并保留原始指针:
int main ()
{
A * a = new B();
A * aa= new C();
std::function<void(int,int)> f1 = [=](int p1, int p2) { return a->method(p1, p2); };
std::function<void(int,int)> f2 = [=](int p1, int p2) { return aa->method(p1, p2); };
f1(1, 2);
f2(2, 3);
}
现在是带有智能指针的变体。如果你的f1
和f2
活不过a
和aa
,你可以这样做:
void test()
{
std::unique_ptr<A> a = std::make_unique<B>();
std::unique_ptr<A> aa = std::make_unique<C>();
std::function<void(int,int)> f1 = [ptr = a.get()](int p1, int p2) { return ptr->method(p1, p2); };
std::function<void(int,int)> f2 = [ptr = aa.get()](int p1, int p2) { return ptr->method(p1, p2); };
f1(1, 2);
f2(2, 3);
}
否则您需要使用shared_ptr
:
void test_shared()
{
std::shared_ptr<A> a = std::make_shared<B>();
std::shared_ptr<A> aa = std::make_shared<C>();
std::function<void(int,int)> f1 = [=](int p1, int p2) { return a->method(p1, p2); };
std::function<void(int,int)> f2 = [=](int p1, int p2) { return aa->method(p1, p2); };
f1(1, 2);
f2(2, 3);
}
此外,如果您不需要std::function
的类型擦除,您应该制作f1
并f2
lambda。 例如auto f1 = [=] ...
相关文章:
- 使用std::multimap迭代器创建std::list
- C++中std::resize(n)和std::shrink_to_fit之间的区别
- 来自 std::list 的迭代器 .end() 按预期返回"0xcdcdcdcdcdcdcdcd"但 .begin()
- C++17复制构造函数,在std::unordereded_map上进行深度复制
- 如何导出包含具有"std::unique_ptr"值的"std::map"属性的
- 从持续时间构造std::chrono::system_clock::time_point
- std::具有相同基类的类的变体
- std::向量与传递值的动态数组
- 使用std::vector的OpenCL矩阵乘法
- std::map<struct,struct>::find 找不到匹配项,但是如果我循环通过 begin() 到 end(),我在那里看到匹配项
- std::condition_variable::wait()如何评估给定的谓词
- 如何获取std::result_of函数的返回类型
- std::原子加载和存储都需要吗
- 将对象移动到std::shared_ptr
- POCO::PostgreSQL:如何将std::vector支持添加到`Binder::bind`
- 绑定派生类方法C++从实例范围之外的分隔 std::function 变量调用
- 使用 STD 正则表达式标记逗号分隔的列表
- 当我使用 std::map 从文件中读取值时,该值会随之",",因为键和值用逗号分隔
- 与std::chrono::system_clock完全分隔的日期(以毫秒为单位)
- std::getline:分隔字符与字符计数