0

I have a virtual function in a base class, taking a parent struct as an argument:

class Parent
{
   struct foo_t {...};
   virtual void set_foo(foo_t &foo) = 0;
};

which I want to override in a derived class, using a child struct:

class Child : public Parent
{
   typedef struct bar_t : Parent::foo_t 
   {
      ...
   } bar_t __attribute__((packed));
   bar_t y{};
   void set_foo(bar_t &x) override { y = x };
};

When I compile like this, I get the error marked 'override' but does not override as the virtual function has a different argument type.

If I change the override to set_foo(foo_t &x) override { y = x }; it doesn't compile as I'm trying to assign a parent struct to a child.

If I then change the assignment to static_cast<foo_t>(&y) == x I get expression must be a modifiable lvalue.

Or if I change the assignment to y = (bar_t*)(&x) it doesn't compile as I'm trying to assign a pointer to a struct.

How to go about this?

georgies
  • 1
  • 1
  • 5
    Overriding a virtual function requires that the signatures are exactly the same. This is looking like an [XY Problem](https://xyproblem.info/). – PaulMcKenzie Jan 03 '22 at 15:46
  • 1
    You cannot change the function signature and `override` at the same time. – πάντα ῥεῖ Jan 03 '22 at 15:48
  • 1
    @PaulMcKenzie They don't need to be exactly the same. They are allowed to have a covariant return type. – NathanOliver Jan 03 '22 at 15:50
  • 2
    Yes, I meant to say that the parameters (and whether the function is `const`, etc.) must be exactly the same. – PaulMcKenzie Jan 03 '22 at 15:51
  • You can make the parent class a template that receives the child class as parameter, that is, use the [curiously recurring template pattern](https://en.wikipedia.org/wiki/Curiously_recurring_template_pattern). – darcamo Jan 03 '22 at 15:56
  • I voted to close as a duplicate since it boils down to "how do I cast a base reference to a derived reference", but tested this specific example on a godbolt https://godbolt.org/z/s5vY3981d – JohnFilleau Jan 03 '22 at 15:56
  • `void set_foo(foo_t& x) override { y = dynamic_cast(x); }` – Eljay Jan 03 '22 at 16:13
  • Question lacks details which are important for this problem. Who and why calls `set_foo`? Solution from @JohnFilleau can be valid or not depending on context which has been stripped. – Marek R Jan 03 '22 at 16:13
  • @darcamo thanks for your suggestion, this would probably be the elegant solution. @JohnFilleau thanks for showing me the correct way of casting on godbolt. I guess you're right it is related to the article you mentioned, however this scenario adds some extra constraint due to the ```override``` which requires the parameters to be similar. Without it I think I would have been allowed to use ```bar_t``` as argument type. – georgies Jan 03 '22 at 16:19

0 Answers0