-1

I'm trying to understand if is possible to call a parent's function member from a child class.

Basically I have the following code:

struct Parent
   {
   template<class... Args>
   void doFoo(Args&&... args)
     {
     std::cout << "parent doFoo";
     }

   template<class... Args>
   void foo(Args&&... args)
     {
     doFoo(args...);
     }
   };

 struct Child : Parent
   {
     template<class... Args>
     void doFoo(Args&&... args)
       {
       std::cout << "child doFoo";
       }
   };

   Child c;
   c.foo(); // This should invoke Child::doFoo()

Is there a simple way to obtain "child doFoo" as output without introducing overhead?

Saturnu
  • 309
  • 1
  • 8
  • Not clear what you mean by 'similar techniques'. You can use [static | dynamic]_cast, for example. – SergeyA Mar 19 '19 at 14:32
  • Ok I'll get rid of that requirement. Every option is ok apart from the ones that introduce overhead. In effect in that way it was not really clear. – Saturnu Mar 19 '19 at 14:35
  • 1
    You are already using the CRTP keyword. Do you have trouble implementing that? – chtz Mar 19 '19 at 17:35
  • I wanted to know if it was possible if there was an alternative way to do that or if CRTP is the only solution. There are also different ways to implement it I think – Saturnu Mar 20 '19 at 08:38
  • I assume there are other solution. But what is wrong with CRTP? – chtz Mar 20 '19 at 10:41
  • @chtz parent would not be usable in containers – Saturnu Mar 20 '19 at 11:41
  • @Saturnu Then state in your question what you actually intend to do! Will the child classes have additional data members? If you have a container which at compile-time is only known to contain `Parent` objects, then in some way you need to encode what actual `Child` objects are stored at each place. – chtz Mar 20 '19 at 14:05
  • Absolutely right about that, question needs refactoring.. I am not speaking about my specific case, just curious about this problem per se. The Child class can have other data members besides those, sure, why shouldn't? – Saturnu Mar 20 '19 at 14:24

1 Answers1

0

I don't know if it's an option but if you can afford to template the class instead of the method, you're allowed to make "doFoo" virtual and then it works as you expect.

#include <iostream>

template <typename ... Args>
struct Parent
   {
   virtual void doFoo(Args&&... args)
     {
     std::cout << "parent doFoo";
     }

   void foo(Args&&... args)
     {
     doFoo(args...);
     }
   };

template <typename ... Args>
 struct Child : Parent <Args...>
   {
     void doFoo(Args&&... args) override
       {
       std::cout << "child doFoo";
       }
   };

int main()
{
   Child<> c;
   c.foo(); // This should invoke Child::doFoo()
}
  • interesting solution, thanks for sharing. Fact is that it uses the virtual keyword and I'd like to avoid any overhead – Saturnu Mar 19 '19 at 15:29
  • 1
    Define what you mean by "overhead", please. Also, you want polymorphism without the virtual keyword, that doesn't even make sense. – Arthur Passos Mar 19 '19 at 15:34
  • Artur: https://en.wikipedia.org/wiki/Template_metaprogramming#Static_polymorphism. Just google virtual c++ overhead to understand what I mean – Saturnu Mar 19 '19 at 15:40
  • 1
    @Saturnu I believe the above polymorphism can be determined at compile time and follows the same idea of CRTP, with that in mind, using the wikipedia link you provided, we have that: **However, in many cases the polymorphic behaviour needed is invariant and can be determined at compile time. Then the Curiously Recurring Template Pattern (CRTP) can be used to achieve static polymorphism, which is an imitation of polymorphism in programming code but which is resolved at compile time and thus does away with run-time virtual-table lookups.** – Arthur Passos Mar 19 '19 at 15:52
  • exactly, I want to determine that at compile time to avoid the "virtual" overhead :) – Saturnu Mar 19 '19 at 16:00
  • 1
    I don't think you understood what I just said, it is determined at compile time, even with the virtual keyword. Please, have a look at this [example](https://godbolt.org/z/x2eHsc) – Arthur Passos Mar 19 '19 at 16:09
  • Yes, I think I didn't . Sorry for that, in this case you're totally right. Really interesting indeed! – Saturnu Mar 19 '19 at 16:13
  • Happy to help :) – Arthur Passos Mar 19 '19 at 16:17