Reputation: 234
I have a template class with 5 template arguments which looks something similar to this.
SomeClass.h
template < typename A, typename B, typename C, typename D >
class SomeClass
{
private:
A a_obj;
B b_obj;
C c_obj;
D d_obj;
public:
void someoperationA();
void someoperationB();
void someoperationC();
};
SomeClass.cpp
template < typename A, typename B, typename C, typename D >
SomeClass<A, B, C, D>::someoperationA()
{
A::someStaticMethods();
}
template < typename A, typename B, typename C, typename D >
SomeClass<A, B, C, D>::someoperationB()
{}
template < typename A, typename B, typename C, typename D >
SomeClass<A, B, C, D>::someoperationC()
{}
Consider the case where my template parameters should be given some good big names like
SomeClass.cpp
template <
typename ABIGCLASSNAME,
typename BBIGCLASSNAME,
typename CBIGCLASSNAME,
typename DBIGCLASSNAME
>
SomeClass<ABIGCLASSNAME,
BBIGCLASSNAME,
CBIGCLASSNAME,
DBIGCLASSNAME>::someoperationA()
{
ABIGCLASSNAME::someStaticMethods();
}
It definitely starts looking ugly :(
So is it possible to typedef template arguments in any way, so that its readable... Something like
typedef template < typename ABIGCLASSNAME, typename BBIGCLASSNAME, typename CBIGCLASSNAME, typename DBIGCLASSNAME > TEMP_WITH_PARAMS
and something simliar for the class other than using #define
Upvotes: 0
Views: 1777
Reputation: 3918
Descriptive template parameters' names are nice. But once you specified them initially, you don't have to drag them around. Two things can help you:
using
to have a short alias inside the class.The fact that you don't have to use same name for template parameter for definitions outside the class.
#include <iostream>
template <typename SomeLongAndUglyName>
class ImPretty {
public:
using SimplyUgly = SomeLongAndUglyName;
void foo();
};
template <typename Ugly>
void ImPretty<Ugly>::foo() {
std::cout << "pretty" << std::endl;
}
Upvotes: 0
Reputation: 93264
Consider creating a wrapper struct
that contains all of your required parameters, and templatize SomeClass
on that:
template < typename A, typename B, typename C, typename D >
struct Settings
{
using AType = A;
using BType = B;
using CType = C;
using DType = D;
};
template < typename TSettings >
class SomeClass { /* ... */ }
template < typename TSettings >
SomeClass<TSettings>::someoperationB() { /* ... */ }
Advantages:
Much less boilerplate.
If you decide to add a new template parameter or change an existing one, you only have to change Settings
.
Preserving your original interface is also trivial with a type trait:
template < typename A, typename B, typename C, typename D >
using SomeClass = SomeClassImpl<Settings<A, B, C, D>>;
Consider using a variadic type trait to avoid repeating A, B, C, D
:
template < typename... Ts >
using SomeClass = SomeClassImpl<Settings<Ts...>>;
Upvotes: 2
Reputation: 75688
No, there isn't.
Be careful, you can't have templated definitions in source (.cpp
) files. See Why can templates only be implemented in the header file?
There was a proposal to define a class namespace where all definitions were considered members of that class, which would have solved your problem, but it didn't get much traction.
So either write all templates paramters (but in headers), or define them inside the class. I personally prefer defining the methods inside class, since I have to define then in headers anyway, I don't see a much advantage to defining them outside of class vs the hassle to write code twice.
Another trick you can do is to have really short template parameter names and have full name aliases in class. E.g.:
template <class F> struct S {
using Function = F;
};
Upvotes: 2