【发布时间】:2021-12-09 22:29:11
【问题描述】:
[更新] 这个问题的原因:
有许多现有的 lambdas 定义为 [](const ChildType1& child),都在一个大注册表中。我们想在同一个注册表中注册新的 lambda,例如 [](const ChildType2& child)。如果我们使用Parent 定义函数包装器,对于许多现有的lambda,我们需要将它们更改为[](const Parent& someone),并在内部从Parent 向下转换为ChildType1。
如果我有一个作为std::function<void(const Parent&)> 的函数包装器,有没有办法允许它采用Parent 子类作为参数的函数,例如[](const Child& child){...},其中Child 是Parent 的子类。
以下内容无法编译。在线IDElink.
#include <iostream>
#include <functional>
class Parent {
public:
virtual void say() const {
std::cout<<"I am parent"<<"\n";
}
};
class Child: public Parent {
public:
void say() const {
std::cout<<"I am child"<<"\n";
}
};
typedef std::function<void(const Parent&)> Wrapper;
int main() {
Wrapper func=[](const Child& child){ // of course works if Child->Parent
child.say();
};
Child c;
func(c);
return 0;
}
【问题讨论】:
-
不,没有办法,这在逻辑上是错误的,因为可以将
Parent传递给需要Child的函数。 -
不,这是错误的方差。请参阅协变和逆变。
-
你有什么不想要的原因
Wrapper func=[](const Parent& child) { .. };?您仍然可以使用Child调用它(并且会调用它的say()函数)。 -
原因是有许多现有的 lambdas 定义为
[](const ChildType1& child),都在一个大注册表中。我们想在同一个注册表中注册新的 lambda,例如[](const ChildType2& child)。如果我们使用Parent定义函数包装器,那么在许多现有的lambda 中,我们需要将Parent向下转换为ChildType1。 -
@Robert 我不明白你为什么需要在这里沮丧。你有多态性,所以你可以使用它。
标签: c++ function polymorphism subclass std-function