简体   繁体   中英

Define all pure virtual functions in abstract base class as a varaidaic template

Can a single variadic function handle all base class pure virtual functions? In the case below Say would override SayGreeting and SayGreetingLocation .

class  Brain {

 private:
  virtual void SayGreeting(std::string greeting) = 0;
  virtual void SayGreetingLocation(std::string greeting, std::string location) = 0;
}

class Mouth: public Brain {

 public:
  Say(){}
  template<typename T, typename... Args>
  void Say(T first, Args... args) {
    std::cout << first;
    Say(args...)
  }
}

I'm not aware of a way to do this automatically, which I assume is what you're asking. I'm not sure there's even a sensible macro hack that can semi-automate it.

Manually forwarding the arguments to the implementation of Say is of course straightforward:

void Mouth::SayGreetingLocation(std::string greeting, std::string location)
{
    this->Say(greeting, location);
}

Some asides:

  • Your Say() funnction will need a 0-parameter "terminating" overload.
  • const std::string& might be a more appropriate type for function parameters as it is typically more efficient. (Unless your function mutates the strings.)

Not directly. Member function templates cannot be virtual and to override a method in the base class the method needs to have the same name and signature. But you can do this:

#include <iostream>
#include <string>

class  Brain {    
private:
    virtual void SayGreeting(const std::string& greeting) = 0;
    virtual void SayGreetingLocation(const std::string& greeting,const std::string& location) = 0;
};

class Mouth: public Brain {    
    template<typename... Args>
    void Say(Args... args) {
        (std::cout << ... << args);
    }
public:
    void SayGreeting(const std::string& greeting) override {
        Say(greeting);
    }
    void SayGreetingLocation(const std::string& greeting, const std::string& location) override {
        Say(greeting,location);
    }
};

There are a couple of mistakes in your code: Missing ; , std::cout << args should be std::cout << first you either need to stop the recursion somehow or not use recursion in the first place. Since C++17 many recursions for templates can be replaced with fold expressions .

PS: This is perhaps just an example, but your inheritance looks odd. A Mouth is not a Brain but public inheritance does model a "is-a" relation.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM