I want to create a pure virtual interface for every type in a variadic template. For example, a class:
overloads_interface<int,float,bool>
That defines the functions:
virtual void overload(const int& arg) = 0
virtual void overload(const float& arg) = 0
virtual void overload(const bool& arg) = 0
And if I add another type to the varaidic template, e.g
overloads_interface<int,float,bool, std::string>
It will automatically add the overload:
virtual void overload(const std::string& arg) = 0
Then, in order to instantiate this class, I must implement the functions, e.g:
class concrete : public overloads_interface<int,float,bool> {
public:
virtual void overload(const int& arg) override { /**handle int**/ }
virtual void overload(const float& arg) override { /**handle float**/ }
virtual void overload(const bool& arg) override { /**handle bool**/ }
};
Here is my best attempt of creating this class:
template<typename... args>
class overloads_interface {
using param_pack = std::tuple<args...>;
static constexpr size_t num_args = sizeof... (args);
template<size_t i = num_args - 1>
struct crtp : public crtp<i - 1> {
using arg = typename std::tuple_element<i, param_pack>::type;
using super = crtp<i - 1>;
using super::overload; // unhide overload from super class
virtual void overload(const arg& arg) = 0;
};
template<>
struct crtp<0> {
using arg = typename std::tuple_element<0, param_pack>::type;
virtual void overload(const arg& arg) = 0;
};
};
But this fails to compile:
/main.cpp:21: error: explicit specialization in non-namespace scope ‘class overloads_interface<args>’
template<>
^
/main.cpp:22: error: template parameters not deducible in partial specialization:
struct crtp<0> {
^~~~~~~
And also has a nested class crtp
that I don't really want.
How could I make this class?