首页 > 解决方案 > 为什么使用与父级一起声明的 std::function 在与子级一起使用时会显示错误?

问题描述

这是位于接口中的虚拟排序函数的声明,使用 std::function。

using Comparefunction = std::function<bool(const DataHandling::GridDataStruct &d1, const 
DataHandling::GridDataStruct  &d2)>;

virtual bool Sort(const Comparefunction& fct);

这是 std::function 寻址的函数:

bool operator() (const Types::Order &d1, const Types::Order &d2)const;

其中 Types::Order 是 GridDataStruct 的子级。

在实例化包含上述运算符的类时使用 std::function:

 Sort(Tools::OrderComparer(grid, false));

->OrderComparer 包含上面显示的运算符

-> 顶部也提到了排序。

如果有任何问题分别不清楚,请随时提出!

简化的错误信息:

没有合适的用户定义的从(包含运算符的类)到(std::function 寻址运算符)的转换

标签: c++inheritancepolymorphismstd-function

解决方案


这归结为

struct Base { virtual ~Base(); };

struct Derived : Base {};

struct Comparer
{
    bool operator()(const Derived&, const Derived&)
    {
        return true;
    }
};

std::function<bool(const Base&, const Base&)> comp(Comparer{});

https://godbolt.org/z/_7Xtfn

comp据说能够比较两个Base实例。但Comparer只能比较Derived实例,所以不能用于初始化comp

或者,重复上面的评论:代码说“Sort想要一个CarComparer”,但你只给它一个PorscheComparer. 编译器对此不满意是完全正确的——如果有人使用CarComparer比较两个梅赛德斯实例怎么办?

也许 aPorscheComparer只会用于比较Porsche实例。表达这一点的简洁方法是Sort在具体汽车类型上模板(或整个接口) - 可能完全消除继承层次结构(用编译时多态性替换它)。


推荐阅读