2

Is there a way to automatically create one method per variadic template argument?

For example, in the code below, I want to be forced to override void x(a &v) and void x(b &v) in class i:

#include <type_traits>
#include <stdlib.h>
#include <stdio.h>

class a {
};

class b {
};

template <typename ...T>
class t {
public:
    virtual void x(T &v) = 0;
};

class i : public t<a, b>
{
};

int
main (int argc, char *argv[])
{
    i ii;
    return 0;
}


NathanOliver
  • 171,901
  • 28
  • 288
  • 402
38489344
  • 138
  • 8

2 Answers2

4

You can make a t_impl that holds the virtual function for a single T like

template <typename T>
class t_impl
{
public:
    virtual void x(T &v) = 0;
};

and then t would inherit from it like

template <typename ...T>
class t : t_impl<T>... // can use public, protected or private inheritance
{
public:
    using t_impl<T>::x...; // used to import t_impl<T>::x into the public space
    // any additional common members
};
NathanOliver
  • 171,901
  • 28
  • 288
  • 402
  • but to make `x()` usable given `t*`, you should add a `using` declaration. – Eugene Oct 28 '20 at 20:39
  • Nice. This is more efficient than what I suggested (for compilation). We should also note that either the user can't list the same type twice, or we'd need to add something here to prevent a second inheritance in that case... – Elliott Oct 28 '20 at 20:42
  • @Eugene Good call. Code fixed. – NathanOliver Oct 28 '20 at 20:45
  • @Elliott Yeah. Adding a static assert with a check from [here](https://stackoverflow.com/questions/18986560/check-variadic-templates-parameters-for-uniqueness) should fix that. – NathanOliver Oct 28 '20 at 20:47
1

Instead of making t a variadic template, just template it on a single type:

template <typename T>
class t {
public:
    virtual void x(T &v) = 0;
};

and inherit base classes like this instead:

class i : public t<a>, t<b>
{
    virtual void x(a &v) {}
    virtual void x(b &v) {}
};

Here's a demo.

cigien
  • 57,834
  • 11
  • 73
  • 112