Domanda

I am deep into a new project which I address with a bunch of templates and specializations of them. Now, after a day without programming, I find myself asking whether it is really worth the extra lines of code.

The question is: What are the advantages of specialization?

Is this:

template <int i> class A {};
template <> class A <1> { void foo() {/* something */}  };
template <> class A <2> { void foo() {/* something else*/}  };
template <> class A <3> { void foo() {/* even different*/}  };

In any way better (faster execution) than

template <int i> class A { 
   void foo() {
      if (i==1) {/* something */}
      else if (i==2) {/* something else*/}
      else if (i==3) {/* even different*/}
   }
};

?

Edit:

The code is part of a library to be used by others. I am using gcc 4.6.3 but in the end the code will be used with different compilers.

Edit:

These two pieces of code result in identical binaries using gcc 4.6.3. I cannot test the full case as my actual code is far from being usable. It really seems to be a matter of principle, versatiliy, reusability, maintanability etc...

È stato utile?

Soluzione

Speed is not the primary issue here, but extensibility is.

Specialization has the advantage that you make it easier for clients of your code to add new overloads of foo(). Suppose you later decide to add new behavior for i=4: in the first approach, you simply add a new specialization; in the second version, you need to modify the function foo(). If you have released your library in binary form, clients will not be happy.

The preference of the specialization approach to the second one is a manifestation of the Open/Closed Principle: code should be open for extension, closed for modification.

Altri suggerimenti

This depends on the compiler in use. I write code like that myself a lot and my compiler does the right thing for me. However, since nothing in the C++ standard requires compilers to be smart in this regard, you may as well get yourself into a trouble. So make sure your compiler does the right thing. As a general rule of thumb - don't rely on this feature if you are writing a reusable library intended to be used by someone else, if you plan to port this code to different compilers and/or exotic environments etc.

You are asking "Why template-specialization is better", but let me say why it is worse. I guess that at least some of the code for i=1, i=2 and i=3 is common (otherwise, why does it have the same name?). If so, you might have to duplicate some code when you go for specialization, and that makes code difficult to maintain.

Code duplication is better left to the compiler, which does it pretty well with these if-elseif-else constructs. You can even have if (i<3), which would be very awkward to implement with specialization.

Of course, if your functions are nearly completely different, you don't get this disadvantage when using template-specialization (and you get the advantages).

Sometimes it is impossible to write the code as one function, because the code valid for i=1 may be invalid for i=2, and even though it is never executed, the compiler chokes!

For example:

template <int i> class A { 
   void foo() {
      if (i==1)
      {
          cout << "Easy";
      }
      else if (i==2)
      {
          int stuff[100 * i - 110] = {42}; // error: negative array size for i=1
          cout << stuff[0];
      }
      else if (i==3)
      {
          /* even different*/
      }
   }
};
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top