1

I would like to ask about guidelines on how to ellegantly use long parameters lists in class templates. The inconviency is that you need to repeat the parameter list twice when defining (templated) methods, consts etc. in the templated class.

The question is similar to this one, but no example code is provided and I still fail to compile most of my attempts. Usually nothing is gained when I move the parameters somewhere else as I only have to define my long list of parameters in another place(constructor, struct etc.).

I will try to give an MWE. I want to achieve something like:

#include <iostream>

template <class MyInt_t, int _N, int _M, MyInt_t _A, MyInt_t _B> class MyClass{
// generally this list is even longer and composed of fundamental classes
// and MyInt_t template type-parameter
  public:
   static const int N = _N, M = _M; // any way not to keep different names
                                    // for params and fields? N = MyPars.N?
   // static const MyInt_t MA[2] = {_A, _B}; // ...but ofc it will not work
   // also cannot (or do not know how to) pass arrays to templates
   static const MyInt_t MA[2];      // another repetition of template parameters below
   MyInt_t getSth();
   // rest of implementation with non-static fields and methods
};

// static const array definition
template <class MyInt_t, int _N, int _M, MyInt_t _A, MyInt_t _B>
         const MyInt_t MyClass<MyInt_t, _N, _M, _A, _B>::MA[2] = {_A,_B};

// and now to defining the method...
template <class MyInt_t, int _N, int _M, MyInt_t _A, MyInt_t _B>
  MyInt_t MyClass<MyInt_t, _N, _M, _A, _B>::getSth(){
    std::cout << "Yey! " << N << ", " << M << " || " << MA[1] << std::endl;
    return MA[0];
  }

typedef MyClass<long long unsigned, 5,6, ~123ull, -5ull> MySpecClass1;
typedef MyClass<long unsigned, 13,19, 123ull, 456ull>    MySpecClass2;

// main()
int main()
{
  MySpecClass1 Obj1;
  long long unsigned test = Obj1.getSth();
  std::cout << "Bye! " << test << " || " << MySpecClass2::N << std::endl;
  return 0;
}

Output:

Yey! 5, 6 || 18446744073709551611
Bye! 18446744073709551492 || 13

Note1: I'm too shy to use preprocessor definitions, but when the list of parameteres has more than ten constant parameters which I notoriously have to repeat then it becomes IMHO not readable. Whereas the purpose of templates is a clean way to utilize your code many times... So I must be doing sth wrong... There is also the problem of having two different names for one parameter: the names of the field and the template non-type constant have to be different.

Note2: I want those to be static constants because they will characterise the whole specialised class and not the instance of it. I also like const because of compiler optimisation.

Summary: I feel the code above is not ellegant and has a tendency to grow a lot uglier when the list of constants is elongating. There is a lot of mathematical algorythms (like random number generators, solvers) that take a long list of static constants.

Community
  • 1
  • 1
Przemek M
  • 55
  • 6
  • Let me also add that, say, there a two types involed, the "int" type, and the "MyInt_t" type. One could sort parameters in two groups (arrays, structs...), but arrays pose different problems in templates (pointers, lengths, references etc.), and as the "MyInt_t" type is unknown it needs to be templated... Just thinking loudly. – Przemek M Jun 14 '15 at 11:22

0 Answers0