0
template <typename T>
void foo(T t)
{
   ... // do stuff with type T
}

template <typename T>
class class_template
{
    // class body
};

template<>                       // failed attempt at full specialization
void foo(class_template<T> t)    // which doesn't work of course
{
    //full specialization for all classes of class_template
} 

In the above code how do I explicitly specialize function foo with a class template?

hawk
  • 1,827
  • 2
  • 14
  • 28
  • 1
    The contradiction here is that if it's "for all classes of class_template", then it's not a "full specialization". A full specialization by definition applies to only *one* possible value of each template parameter. – Steve Jessop May 17 '12 at 14:02
  • Your attempt has `template<>` but then uses an undeclared template parameter `T`, which can't work, what is `T`? As the previous comment says, you're using the wrong terminology, what you're trying to do is **partially** specialize a function template, which isn't allowed. – Jonathan Wakely May 17 '12 at 15:42

1 Answers1

1

In the above code how do I explicitly specialize function foo with a class template?

You cannot. This is the whole point of partial specialisations. But they don’t work for functions.

You have two solutions:

  • Overload the function. This usually works.
  • Refer the work to a class template, which can be partially specialised. That is, inside your function, call a (static) function in a class template, and specialise that.
Konrad Rudolph
  • 530,221
  • 131
  • 937
  • 1,214
  • I don't think I have either choice, as my function foo is std::swap. – hawk May 17 '12 at 14:05
  • @hawk: Because you're still requiring a template parameter. For example, `template<> void foo< class_template > (class_template t)` is legal because it no longer has a template argument. Where you want to say, "for all class_templates, do this", which is not. – Dave S May 17 '12 at 14:05
  • 1
    @hawk Just overload `std::swap` in the local namespace. This is the preferred way. – Konrad Rudolph May 17 '12 at 14:07
  • @hawk: One other thing, rather than specialize std::swap, use function overloading, which is how the STL containers work. In the same namespace as your class_template, put `template swap(class_template &lhs, class_template& rhs) {...}`. – Dave S May 17 '12 at 14:08
  • 2
    @hawk: you should ADL-overload `swap` (that is, define a function `swap` in the same namespace as `class_template`). If you're paranoid also check that your standard library does `swap(a,b);` rather than `std::swap(a,b);` in algorithms like `sort`. Users of swap should use it like `using std::swap; swap(a,b);`. – Steve Jessop May 17 '12 at 14:08
  • @Steve Jessop - Yea that's what I was worried about. How do I check that? – hawk May 17 '12 at 14:09
  • @hawk: either look at the source, or sort some of your objects and log how many times their copy constructors are called. – Steve Jessop May 17 '12 at 14:10
  • @hawk: Or you could put a printout in your swap function to see if it's being invoked when you sort. – Dave S May 17 '12 at 14:27