У меня есть шаблонный тип не-типа template<std::size_t N> Derived<N>
, который наследуется от некоторого базового класса не-шаблона Base
:
class Base
{
public:
double some_value;
// Some methods and variables that do not depend on N
// I wish to keep these in a non-templated class
virtual const size_t get_N() = 0;
virtual ~Base() = default;
Base(double value): some_value {value} {};
};
template <std::size_t N>
class Derived: public Base
{
public:
double some_other_value;
// Some functions and variables, for which
// the types and actions depend on N
const size_t get_N() override
{
return N;
}
Derived(double value1, double value2): Base(value1), some_other_value {value2} {};
};
Теперь у меня есть функция call_by_base(Base& my_base)
, которая использует только переменные-члены/ функции объявлены в Base
.Единственное исключение из этого, это звонок на template<std::size_t N> void call_by_derived(Derived& my_derived)
.Поскольку почти вся функция call_by_base
не зависит от параметра шаблона, я бы предпочел оставить эту функцию без шаблонов.
Я попытался достичь вышеописанного с помощью реализаций, аналогичных следующим:
template<std::size_t N>
void call_by_derived(Derived<N>& my_derived)
{
std::cout << "in call_by_derived" << std::endl;
// Methods that use the functions and variables in Derived.
}
void broken_call_by_base(Base& my_base)
{
std::cout << "in call_by_base" << std::endl;
// Manipulations independent of child
// type Derived<N>
auto derived = dynamic_cast<Derived<my_base.get_N()>&>(my_base);
call_by_derived(derived);
// Manipulations independent of child
// type Derived<N>
}
Когда я пытаюсь скомпилировать этот код, я получаю error: expression ‘Base::get_N’ is not a constant-expression
.Я пытался устранить эту ошибку, пытаясь изменить что-то другое, как в моем базовом, так и в производном классе.Все это было безуспешно.
Мне удалось найти следующую альтернативу работе:
void working_call_by_base(Base& my_base)
{
std::cout << "in call_by_base" << std::endl;
if(my_base.get_N()==2)
{
auto derived = dynamic_cast<Derived<2>&>(my_base);
call_by_derived(derived);
}
if(my_base.get_N()==3)
{
auto derived = dynamic_cast<Derived<3>&>(my_base);
call_by_derived(derived);
}
}
Это, однако, очень утомительно, особенно когда N
может принимать гораздо больше значений.Есть ли способ заставить функцию работать по принципу broken_call_by_base
?То есть: Как я могу преобразовать не шаблон Base
в шаблон не-типа Derived<N>
?
пс.Будет создан только объект типа Derived<N>
.Это код в main
для проверки:
int main()
{
Derived<3> test(1.0,2.0);
working_call_by_base(test);
broken_call_by_base(test);
call_by_derived(test);
}