I've the following template, which scope is only to create some using
declarations that I need elsewhere:
template<
typename VariableType,
size_t StateSize,
template<size_t, typename> typename IntegrationStrategy
>
class Configuration {
public:
using State = std::array<VariableType, StateSize>;
using Strategy = IntegrationStrategy<StateSize, VariableType>;
using Var = VariableType;
};
It seems to work, because this code compiles:
template <size_t StateSize, typename VariableType>
class RungeKutta4 {
};
// ...
using Conf = Configuration<double, 5, RungeKutta4>;
static_assert(std::is_same_v<double, Conf::Var>);
static_assert(std::is_same_v<std::array<double, 5>, Conf::State>);
static_assert(std::is_same_v<RungeKutta4<5, double>, Conf::Strategy>);
Now I want to use the Configuration
as template argument in another class, because I need to use Var
, State
, and Strategy
that it defines:
template <Configuration Conf>
class DifferentialEquation {
public:
void dummy(const Conf::State& state) {}
};
Unfortunately this code does not compile. I've also tried something like template template parameters:
template <template<
typename,
size_t,
template<size_t, typename> typename> typename Conf>
class DifferentialEquation {
public:
void dummy(const Conf::State& state) {}
};
But it does not work.
What should I use as template argument in my DifferentialEquation
class in order to use the using
declaration inside my Configuration
specialization, and use Conf::State
in methods and parameters inside that class?
EDIT:
This is the error when I try to compile the last DifferentialEquation
:
\DifferentialEquation.hpp(22): error C3205: argument list for template template parameter 'Conf' is missing
/DifferentialEquation.hpp(40): note: see reference to class template instantiation 'DifferentialEquation<Conf>' being compiled
\DifferentialEquation.hpp(22): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
\DifferentialEquation.hpp(22): error C2144: syntax error: 'unknown-type' should be preceded by ')'
\DifferentialEquation.hpp(22): error C2144: syntax error: 'unknown-type' should be preceded by ';'
\DifferentialEquation.hpp(22): error C2039: 'State': is not a member of '`global namespace''
\DifferentialEquation.hpp(22): error C2143: syntax error: missing ';' before '&'
\DifferentialEquation.hpp(22): error C2059: syntax error: ')'
\DifferentialEquation.hpp(22): error C2334: unexpected token(s) preceding '{'; skipping apparent function body
ninja: build stopped: subcommand failed.
EDIT:
I'm trying to follow suggestion in order to add template arguments to Conf
, but I'm not able to add the third argument, the template one.
If I add names to template arguments it compiles:
template <template<
typename X,
size_t Y,
template<size_t, typename> typename Z> typename Conf>
class DifferentialEquation {
public:
// void dummy(const Conf::State& state) {}
};
But when I try to use it does not compile:
template <template<
typename X,
size_t Y,
template<size_t, typename> typename Z> typename Conf>
class DifferentialEquation {
public:
void dummy(const Conf::State<X, Y, Z>& state) {} // error
void dummy(const Conf<X, Y, Z<Y, X>>::State& state) {} // error
};
What's the right combination that I should use?
What should I use as template argument in my DifferentialEquation class in order to use the using declaration inside my Configuration specialization, and use Conf::State in methods and parameters inside that class?
The common way(syntax-wise) of doing this is by adding the template parameters needed for the Conf
to the top most template parameter list as shown below:
template <template<
typename,
size_t,
template<size_t, typename> typename> typename Conf,
//note these next three parameter are added so that we can used them as arguments of Conf
typename T,
std::size_t t,
template<size_t, typename>typename temp>
class DifferentialEquation {
public:
void dummy(const typename Conf<T, t, temp>::State& state) {} //works now
};
Also, wherever needed(if any) do add the typename
or template
keyword in the above code.