2

I have a simple interface setter:

template<typename Interface>
struct FrontEnd
{
  virtual void inject(Interface*& ptr, Client* client) = 0;
}

I want to implement these interfaces through parameter packs like this:

template<typename ... Is>
struct BackEnd : public FrontEnd<Is>...
{
   void inject(Is*& ptr, Client* client) override
   {
      ptr = someStuff<Is>.get(client);
   }
};

However this fails with parameter pack not expanded with '...'. I couldn't find something similar to this in cppref. I have no clue where the expansion loci should go (assuming this is even legal, which I'm leaning toward no). Any idea how to provide overrides for every type in a parameter pack?

lurscher
  • 25,930
  • 29
  • 122
  • 185
  • FrontEnd only accepts one interface template parameter, so you can't use parameter packs in your inheritance anyway. So what are you trying to do? Mixing templates with virtual functions isn't really what I would recommend anyway. https://stackoverflow.com/questions/2354210/can-a-class-member-function-template-be-virtual) – Pepijn Kramer Dec 16 '21 at 18:45
  • @PepijnKramer, the first ... is expanding FrontEnd so for every Is, BackEnd has a base class that it should be able to override – lurscher Dec 16 '21 at 18:46
  • @PepijnKramer I'm already aware that virtual methods cannot be templated, and as a matter of fact, `inject` is not a method template – lurscher Dec 16 '21 at 18:48
  • Sorry guys I missed that, and I was a bit too quick to answer. – Pepijn Kramer Dec 16 '21 at 18:53
  • There is an exhaustive list of allowed expansion loci, and the one you want just isn't there. – n. m. could be an AI Dec 16 '21 at 18:53
  • @lurscher list of allowed expansion loci: https://en.cppreference.com/w/cpp/language/parameter_pack#Expansion_loci – Super-intelligent Shade Dec 16 '21 at 19:09

1 Answers1

5

You probably want something like this

  template<typename Is>             
  struct OneBackEnd : public FrontEnd<Is>
  {                                 
     void inject(Is*& ptr, Client* client) override { /* whatever */ }
  };                                
                                    
  template<typename ... Is>         
  struct BackEnd : public OneBackEnd<Is>...
  {                                 
      using OneBackEnd<Is>::inject...;
  };                       
n. m. could be an AI
  • 112,515
  • 14
  • 128
  • 243