Specialize function templates versus function overloads against class

According to this article from Herb Sutter, you should always choose the Specialized Class for Function Overloading and specifically over specialized function templates .

The reason is that

  • Specializations do not overload. Overload resolution selects only the base template (or function without function, if any). Only after it is decided which base template will be selected, and this choice is blocked, will the compiler look around to see if there is a suitable specialization for this template, and if that helps the specialization.
  • We cannot use special function templates.

I must admit that before I read the article, I hit my head on the wall several times. Why doesn’t he choose my specialized function ... After reading the article, Ive never used specialized function templates.

Example:

template <class T> void foo( T t); 

We need to write foo so that we can specialize in class templates, not a specialized function.

 template<class T> struct FooImpl; template <class T> void foo( T t) { FooImpl<T>::foo(t); } 

Now we can specify a template and we don’t have to worry about overload rules, and we can even specialize the partitial template as follows:

 template<class U, class V> struct FooImpl< QMap< U, V > >; 


That is the question.

Do StackOverflow members seem to prefer specialized function templates?
Why? Because specialized function templates gain much more speed than overload solutions and specialized classes.
With the information that I have at the moment, I find it flawed because I know that I can fix it, but I know that the one who comes for me will hit the wall.

There are already some links to the GOTWCA article, so you should read the article. This means that activists should have additional information, please stand and enlighten me.

+7
c ++ templates
source share
4 answers

The problem with the explicitly specialized function template applies only if the function is also overloaded:

 template <typename T> void foo (T*); // #1 template <typename T> void foo (T); // #2 template <> void foo<int*> (int*); int main () { int * i; foo (i); // Calls #1 not specialization of #2 } 

Without overload # 1, the code will work as expected. However, a function that starts without overloading may have overloads added while saving code in the future.

This is one of those examples where, although I don't want to say this, C ++ has too many ways to do the same. Personally, if you find that you need to specialize a function template, I like the template suggested by TimW in his comment against Neil Butterworth, i.e. This is best done if the current function sends a call to the template of a specialized class:

 template <typename T> class DoFoo { static void do (T) { /* default behaviour */ } }; template <> class DoFoo<int*> { static void do (int*) { /* int * behaviour */ } }; template <typename T> void foo (T t) { DoFoo<T>::do (t); } 

If "foo" is overloaded, then at least it is more clear to the developer that this function will not be called, i.e. a developer does not need to be a standards guru to know how specialization rules interact with overload resolution.

Ultimately, however, the code generated by the compiler will be the same, it’s just a problem for the developer to understand the code.

+4
source share

You assume that SO voters - all gurus - are not. Many technically incorrect answers were successful.

As an author, the answer that I think you are referring to is , well, as I said in my comment, this is not a problem. I adore (or know) all this because I very rarely use the specialization template. I suggested that I could remove the answer, but it is technically correct and seems to have caused some useful debate on this topic.

And note that currently it takes the third place in points (probably after that it decreases), and another answer, which uses a completely different approach to the problem, was accepted.

+3
source share

As Neil noted, most of the correct answers will be voted. And the answers already at the top, as a rule, get even more advantages in my experience.

Why: I think specialized function templates are easier to understand, so this makes them preferable in the sample code.

+2
source share

First of all, I am not a supporter (what are you talking about).

Votes usually do not justify correctness; there are even slightly incorrect answers that were accepted, plus upvotes are often related to the time when a specific answer was sent, etc.

To your problem and article: I read the article, and I see no argument in favor of what you propose, which does not apply to overloading a simple function (template). The trick basically does the same thing as the compiler if you used specialized template functions (including partial if allowed), with all the flaws Herb Sutter says in the article. So, I don’t think that your path is “right” (according to your words), I just think that this is an ugly way to achieve something that you do not need.

For comparison:

Your private specialization:

 template<class U, class V> struct FooImpl< QMap< U, V > >; 

Function overload:

 template<class U, class V> void foo(QMap< U, V > ) { ... } 

and etc.

Even SFINAE is possible, partial ordering of a function (template) follows almost the same rules as allowing specialization of templates ...

+2
source share

All Articles