views:

47

answers:

2

Consider something like...

template<typename T>
class Vector {
  ...
  bool operator==( const Vector<float> &rhs ) {
    // compare and return
  }

  bool operator==( const Vector<T> &rhs ) {
    // compare and return
  }
  ...
 };

Notice how the specialization is above the non specialized version. If I were to put the specialized version below the non-specialized version, would a Vector<float> == comparison still work as intended? For some reason I think I remember reading that if you put the specialization below in this scenario then when the compiler looks through the header, it will see the default first, see that it works, and use that.

A: 

As written, I believe you have an error. You aren't specializing operator==, you're overloading it. You aren't allowed to overload on a template parameter like that.

If your method were a free function, then you could specialize it. For instance

template <typename T>
void Foo(Vector<T> x) {
   std::cout << "x" << std::endl;
}
template <>
void Foo(Vector<float> y) {
   std::cout << "y" << std::endl;
}

...
Vector<int> intVec;
Vector<float> floatVec;
Foo(intVec); //prints x
Foo(floatVec); //prints y

In this case, if you call Foo with Vector<float>, you'll call the specialized version.

Order matters to some degree. First of all, the compiler will always favor a specialization over an unspecialized form when one is available. After that, the compiler will try to instantiate each function in order. If it can compile it successfully, that specialization will be used. If it can't, it will move on to the next one. This principle s called Substitution Failure is not an Error (SFINAE). http://en.wikipedia.org/wiki/Substitution_failure_is_not_an_error has a much more detailed description.

JRM
Sorry to unanswer, but I am still having problems with this. Your solution works, but I'm having trouble in general with how specializing member functions based on the template argument of the class works.
floogads
@floogads - Have you considered specializing the entire class? After your class declaration, you could declare a specialization of Vector for floats. `template <> class Vector<float> {...};` It requires you to reimplement the entire class, but you can define the behaviour for a specific template argument, even giving the class a different interface if you desire.
JRM
The overloading in the question is fine, specialization is overkill here. @flo
Georg Fritzsche
@Georg Fritzsche - The overload in his example will result in an ambiguous overload for T = float. This is an error. If you try to instantiate `Vector<float>`, you will get a compiler error.
JRM
Good point. But still, for all other types the overload is fine. You could mention what case you mean in the first paragraph.
Georg Fritzsche
+1  A: 

Your example code is not specializing, but overloading. The order does matter (not in your code though), because functions need to be declared before being known in C++. So if one overload calls another, or if another function in between calls the overload set, calls may end up somewhere not desired. Your example code is valid and common.

For some reason I think I remember reading that if you put the specialization below in this scenario then when the compiler looks through the header, it will see the default first, see that it works, and use that.

You are thinking of the following rule

If a template, a member template or the member of a class template is explicitly specialized then that specialization shall be declared before the first use of that specialization that would cause an implicit instantiation to take place, in every translation unit in which such a use occurs; no diagnostic is required.

I can't help but to quote the hilarious sayings of the Standard here about specializations

The placement of explicit specialization declarations for function templates, class templates, member functions of class templates, static data members of class templates, member classes of class templates, member class templates of class templates, member function templates of class templates, member functions of member templates of class templates, member functions of member templates of non-template classes, member function templates of member classes of class templates, etc., and the placement of partial specialization declarations of class templates, member class templates of non-template classes, member class templates of class templates, etc., can affect whether a program is well-formed according to the relative positioning of the explicit specialization declarations and their points of instantiation in the translation unit as specified above and below. When writing a specialization, be careful about its location; or to make it compile will be such a trial as to kindle its self-immolation.

Johannes Schaub - litb