У меня есть некий класс, который хранит id и несколько методов и наследники, которые меняют некоторые методы (здесь я максимально упростил код, чтобы ничего лишнего не мешало):
...template<uint8_t i>
struct Id {
constexpr static uint8_t id = i;
// какие-то элементы класса с методами
};
struct first : public Id<1> {
// переопределение методов
};
struct second : public Id<2> {
// переопределение методов
};
Также есть класс, который имеет внутреннюю структуру работы, которая может немного меняться в зависимости от того какой id был передан классу. Изначально я его реализовал примерно так:
...struct Class {
template<class Text>
Class& operator<<(const Text& text) {
cout << text << endl;
return *this;
}
template<uint8_t i>
Class& operator<<(const Id<i>& text) {
cout << (int)i << endl;
return *this;
}
};
Но при проверке работы получается так, что классы наследники попадают не в тот оператор и компилятор не может скомпилировать код:
...int main() {
Class c;
c << "hello"; // работает
c << Id<0>(); // работает
c << first(); // не работает
c << second(); // не работает
return 0;
}
Я в принципе примерно понял почему он не туда попадает. Поэтому я написал функцию, которая проверяет является ли объект наследником и переделал оператор и всё заработало:
...template<class A, uint8_t a, uint8_t end>
constexpr bool check() {
if constexpr (is_base_of<Id<a>, A>::value) { return true; }
else if constexpr (a == end) { return false; }
else {
return check<A, uint8_t(a + 1), end>();
}
}
template<class A>
constexpr bool check() {
if constexpr (is_base_of<Id<0>, A>::value) { return true; }
else {
return check<A, 1, 0>();
}
}
struct Class {
template<class Text>
Class& operator<<(const Text& text) {
if constexpr(check<Text>()) {
cout << (int)text.id << endl;
}
else {
cout << text << endl;
}
return *this;
}
};
Но выглядит как-то не очень, и к тому же я попробовал вместо uint8_t поставить простой int и тогда компилятор снова отказывался компилировать (в принципе я его понять могу мало кому захочется проверять все возможные int =) )
Как ещё можно решить данную проблему с наследниками?