I am trying to use std::conditional to implement static inheritance.
I have two possible parents of my child class, parent_one, which should hold multiple variables based on passed types, and parent_two, which takes two types. I am using tag dispatching to differ between the classes I want to inherit from.
Now to the problem. When I am calling child and tagging it to inherit from parent_one with two types, it works as intended. However, if I try to pass any number of types into the child with the intention of inheriting from parent_one, I get error:
static_polymorphism.cpp: In instantiation of ‘class child<foo_type, int, int, double, float>’:
static_polymorphism.cpp:110:41: required from here
static_polymorphism.cpp:99:7: error: wrong number of template arguments (4, should be 2)
99 | class child : public std::conditional_t<
| ^~~~~
static_polymorphism.cpp:90:7: note: provided for ‘template<class T, class F> class parent_two’
90 | class parent_two {
| ^~~~~~~~~~
static_polymorphism.cpp: In function ‘int main(int, char**)’:
static_polymorphism.cpp:111:9: error: ‘class child<foo_type, int, int, double, float>’ has no member named ‘log’
111 | first.log();
If I understand that correctly the compiler should generate code based on my tag dispatching. That means it should create overloaded classes - N(Based on types passed) from parent_one and M(Based on types passed as well) from parent_two. However for some reason, unknown to me, it is not accepting the variable count of types. Could you tell me what am I doing wrong please?
Implementation is here.
using one_t = struct foo_type{};
using two_t = struct bar_type{};
template <typename ... TYPES>
class parent_one {
public:
parent_one() = default;
void log() {
std::cout << "parent_one" << std::endl;
}
};
template <typename T, typename F>
class parent_two {
public:
parent_two() = default;
void log() {
std::cout << "parent_two" << std::endl;
}
};
template <typename T, typename ... ARGS>
class child : public std::conditional_t<
std::is_same_v<T, one_t>,
parent_one<ARGS...>,
parent_two<ARGS...>
>
{
public:
child() = default;
};
int main(int argc, char *argv[]) {
child<one_t, int, int, double, float> first;
first.log();
child<two_t, int, int> second;
second.log();
return 0;
}