How to avoid duplicating class template specifications for each member function?

If I have a template class specification, for example,

template <typename T> class MyClass { public: void fun1(); // ... void funN(); }; template <typename T> void MyClass<T>::fun1() { // definition } // ... template <typename T> void MyClass<T>::funN() { // definition } 

If I changed the class template to something else, I will say that I am adding an additional parameter:

 template <typename T, typename U> class MyClass { // ... }; 

Then I need to change each function definition (fun1, ..., funN) to agree with the specification of the class template:

 template <typename T, typename U> void MyClass<T,U>::fun1() { //... } 

Are there any strategies to avoid this? Can I use macros, for example.

 #define DFLT_TEMPLATE template<typename T, typename U> #define DFLT_CLASS class<T,U> DFLT_TEMPLATE void DFLT_CLASS::fun1() { // ... } 

Or is this considered bad practice?

+6
c ++ templates
source share
7 answers

For me, the benefits of using a macro here are far behind the disadvantages. Yes, if you use a macro, then if you ever need to add an additional template parameter, you will only need to make one modification. But anyone who reads your code is likely to vomit.

I mean, are you going to do this for every template that you have? Your code will be infected with ugly macros.

+5
source share

How many member functions do you have, what is the problem?

I think that either they are small enough to be defined in the class template , or the adaptation of their algorithms to an additional template parameter would significantly outweigh the replacement of these functional headers.

In addition, your editor should do this for you at any time.

+2
source share

yes, you could, but remember to use "#undef DFLT_TEMPLATE" and "#undef DFLT_CLASS" at the end of the file to avoid compiler warnings if your project has multiple templates with the same macro definitions

+1
source share

Inheritance is better than macro.

If you want to change only a few functions and variables, make a specialized class inherit a common class that provides common functions / variables.

+1
source share

If possible, put function definitions in the class template definition. This is a template, so if you are not using the Comeau compiler, it is not as if they will be disabled in another TU.

If functions use what is defined between the class definition and the function definition, then you can play tricks to make this thing dependent on the template parameter, even when it really isn’t. For example:

 template <typename T> struct Foo { void usebar(); }; struct Bar { int a; Foo<int> circularity; // circular dependency between Foo and Bar Bar() : a(3) {} }; template <typename T> void Foo<T>::usebar() { Bar b; std::cout << ba << "\n"; } 

becomes:

 // we only have to write "same" once template <typename T, typename U> struct same { typedef U type; }; struct Bar; template <typename T> struct Foo { void usebar() { typename same<T,Bar>::type b; std::cout << ba << "\n"; } }; struct Bar { int a; Foo<int> circularity; // circularity gone Bar() : a(3) {} }; 

Or actually in this case, simply:

 struct Bar; template <typename T, typename B = Bar> struct Foo { void usebar() { B b; std::cout << ba << "\n"; } }; struct Bar { int a; Foo<int> circularity; Bar() : a(3) {} }; 

All cases support the following code:

 int main() { Foo<int> f; f.usebar(); } 
+1
source share

I would consider this approach a bad practice. What are you complaining about is that you changed your design (you need an additional template parameter) and now want to save kludge as you type?

Introducing macros will reduce the readability of your code. The preprocessor definitions certainly have their place, but personally, I will never defend it on the grounds that they cannot bother me in order to change my functions.

0
source share

There are probably some (more or less bad) workarounds, but you definitely point to the "missing" C ++ function: class namespace extension .
Some people have already suggested extending C ++ in this way:
http://www.lrde.epita.fr/dload//20080709-Seminar/ordy-classnamespaces.pdf

 namespace foo { class bar { typedef int baz_t; baz_t my_method (); }; } namespace class foo::bar { baz_t my_method () { // ... } } 

- Using a macro page is not a good idea (common things about macros ....). I would prefer, in the worst case, to write the definition of the members of the inline function in this case, or even better use an editor than can help you easily update the class definition.

Macros are bad because they allow you to write code editing functions where you should write programs. If you want to edit the code, use your editor (sed, Mx replace- *, Find & Replace ...)

0
source share

All Articles