I have a non-type template class template<std::size_t N> Derived<N>
which derives from some non-template base class 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} {};
};
Now I have a function call_by_base(Base& my_base)
, which only uses member variables/functions declared in Base
. The only exception to this, is a call to template<std::size_t N> void call_by_derived(Derived& my_derived)
. Since almost the entire function call_by_base
is independent of the template parameter, I would prefer to keep this function non-templated.
I tried to achieve the above with implementations along the lines of:
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>
}
When I try to compile this code, I get error: expression ‘Base::get_N’ is not a constant-expression
. I tried to resolve this error by trying to change different thing, both in my Base and Derived class. This was all without success.
I managed to get the following alternative to work:
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);
}
}
This is however very tedious, especially when N
can take on many more values. Is there any way to get a function along the lines of broken_call_by_base
working? That is: How can I downcast a non-template Base
to a non-type template Derived<N>
?
ps. Only object of the Derived<N>
type will be created. This is the code in main
to test:
int main()
{
Derived<3> test(1.0,2.0);
working_call_by_base(test);
broken_call_by_base(test);
call_by_derived(test);
}