Template specialization of a single method from a templated class

64,853

Solution 1

As with simple functions you can use declaration and implementation. Put in your header declaration:

template <>
void TClass<int>::doSomething(std::vector<int> * v);

and put implementation into one of your cpp-files:

template <>
void TClass<int>::doSomething(std::vector<int> * v) {
 // Do somtehing with a vector of int's
}

Don't forget to remove inline (I forgot and thought this solution will not work :) ). Checked on VC++2005

Solution 2

You need to move specialization definition to CPP file. Specialization of member function of template class is allowed even if function is not declared as template.

Solution 3

There is no reason to remove the keyword inline.
It does not change the meaning of the code in anyway.

Solution 4

If you want to remove the inline for whatever reason the solution of maxim1000 is perfectly valid.

In your comment, though, it seems you believe that the inline keyword means that the function with all his contents gets always inlined but AFAIK that is actually very much dependent on your compiler optimization.

Quoting from the C++ FAQ

There are several ways to designate that a function is inline, some of which involve the inline keyword, others do not. No matter how you designate a function as inline, it is a request that the compiler is allowed to ignore: the compiler might inline-expand some, all, or none of the places where you call a function designated as inline. (Don’t get discouraged if that seems hopelessly vague. The flexibility of the above is actually a huge advantage: it lets the compiler treat large functions differently from small ones, plus it lets the compiler generate code that is easy to debug if you select the right compiler options.)

So, unless you know that that function will actually bloat your executable or unless you want to remove it from the template definition header for other reasons, you can actually leave it where it is without any harm

Solution 5

I'd like to add that there is still a good reason to keep the inline keyword there if you intend to leave also the specialization in the header file.

"Intuitively, when you fully specialize something, it doesn't depend on a template parameter any more -- so unless you make the specialization inline, you need to put it in a .cpp file instead of a .h or you end up violating the one definition rule..."

Reference: https://stackoverflow.com/a/4445772/1294184

Share:
64,853
Chuim
Author by

Chuim

Updated on November 15, 2020

Comments

  • Chuim
    Chuim over 3 years

    Always considering that the following header, containing my templated class, is included in at least two .CPP files, this code compiles correctly:

    template <class T>
    class TClass 
    {
    public:
      void doSomething(std::vector<T> * v);
    };
    
    template <class T>
    void TClass<T>::doSomething(std::vector<T> * v) {
      // Do something with a vector of a generic T
    }
    
    template <>
    inline void TClass<int>::doSomething(std::vector<int> * v) {
      // Do something with a vector of int's
    }
    

    But note the inline in the specialization method. It is required to avoid a linker error (in VS2008 is LNK2005) due to the method being defined more then once. I understand this because AFAIK a full template specialization is the same as a simple method definition.

    So, how do I remove that inline? The code should not be duplicated in every use of it. I've searched Google, read some questions here in SO and tried many of the suggested solutions but none successfully built (at least not in VS 2008).

    Thanks!