quitely_zealous
quitely_zealous

Reputation: 37

Why does using a std::function declared with the parent show me an error when used with a child?

This is the declaration of the virtual Sort-function located in an interface, using a std::function.

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

virtual bool Sort(const Comparefunction& fct);

This is the function adressed by the std::function:

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

where Types::Order is a child of GridDataStruct.

The std::function is used while the class containing the operator above is instantiated:

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

->OrderComparer contains operator showed above

-> Sort also has been mentioned at the top.

If there are any questions respectively a lack of clarity, feel free to ask!

Simplified error message:

No suitable user-defined conversion from (Class containing the operator) to (std::function adressing operator)

Upvotes: 0

Views: 117

Answers (2)

Lightness Races in Orbit
Lightness Races in Orbit

Reputation: 385144

You're presenting an interface that can take two of anything that derives from DataHandling::GridDataStruct.

However, the actual implementation can only take two Types::Orders, a more specific, more derived class.

I think you have your expectations backwards here.

Upvotes: 1

Max Langhof
Max Langhof

Reputation: 23691

This boils down to

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 is supposedly able to compare two Base instances. But Comparer can only compare Derived instances, so it cannot be used to initialize comp.

Or, to repeat the above comment: The code says "Sort wants a CarComparer" but you only give it a PorscheComparer. The compiler is completely right to be unsatisfied with that - what if somebody uses the CarComparer to compare two Mercedes instances?

Maybe a PorscheComparer will only ever be used to compare Porsche instances. The clean way to express this would be to template Sort (or the entire interface) on the concrete car type - possibly eliminating the inheritance hierarchy entirely (replacing it with compile-time polymorphism).

Upvotes: 2

Related Questions