Jeevaka Jeevaka - 1 month ago 6
C++ Question

How to create a uni-parameter template from a dual-parameter template to use as a base class template template parameter

Below is an example of what I am trying to do. I am just using it to illustrate the problem.

#include <iostream>
using namespace std;

template <int STEP, bool SIDE> class Stepper {
int step( int x ) {
return SIDE ? x + STEP : x - STEP;
}
};

template <template <bool> typename STEPPER> class DualStepper {
STEPPER<true> upStepper;
STEPPER<false> downStepper;

pair<int , int> step( int x ) {
return pair<int , int>( upStepper.step( x ), downStepper.step( x ) );
}
};


template <int STEP> class FixedDualStepper : public DualStepper<template <bool SIDE> using FT = Stepper<STEP, SIDE>> {

};


int main() {

FixedDualStepper<5> stepper;
pair<int, int> x = stepper.step( 10 );
cout << x.first << '\t' << x.second << endl;

return 0;
}


For this I get the error:

/Work/Learn/04PartialTemplate/main.cpp:23:115: error: template argument 1 is invalid
template <int STEP> class FixedDualStepper : public DualStepper<template <bool SIDE> using FT = Stepper<STEP, SIDE>> {
^
/Work/Learn/04PartialTemplate/main.cpp: In function ‘int main()’:
/Work/Learn/04PartialTemplate/main.cpp:31:29: error: ‘class FixedDualStepper<5>’ has no member named ‘step’
pair<int, int> x = stepper.step( 10 );


Is there a syntax I could use in

... : public DualStepper< ??? >


to get the desired effect. I.e. set the first parameter of
Stepper
to
STEP
and get a single parameter class template to use as a template template parameter for
DualStepper
?

Answer

You can use a struct and an using declaration to do that.
It follows a minimal, working example:

template <int STEP, bool SIDE>
class Stepper {};

template<int S>
struct Type {
    template<bool b>
    using TStepper = Stepper<S, b>;
};

template<template<bool> class C>
void f() {}

int main() {
    f<Type<0>::TStepper>();
}

In your case, it would be:

template <template <bool> class STEPPER>
class DualStepper {
    // ....
};


template <int STEP>
class FixedDualStepper
    : public DualStepper<Type<STEP>::template TStepper> {
    // ...
};