Search code examples
c++templatesarguments

using template class using directive into another template


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?


Solution

  • 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 
    };
    

    Working demo


    Also, wherever needed(if any) do add the typename or template keyword in the above code.