views:

72

answers:

2

Is there a difference between the following approaches?

// approach 1
namespace std
{
    template<>
    void swap<Foo>(Foo& x, Foo& y)   // note the <Foo>
    {
        x.swap(y);
    }
}

// approach 2
namespace std
{
    template<>
    void swap(Foo& x, Foo& y)
    {
        x.swap(y);
    }
}

I stumpled upon this when I tried to specialize swap for my own string type and noticed that swap<::string> doesn't work, but for a completely different reason :)

+8  A: 

Yes, there is. But not in that particular example. If the parameter is not deduced, it can make a difference

template<typename T> void f(typename T::type t);

You cannot specialize that without <type> because it cannot deduce what T is from the parameter list.

struct MyType { typedef int type; };

// needs <MyType>
template<> void f<MyType>(int t) { }

Of course in your case, it's the digraph <: that's meaning the same as [ causing your problem. Put a space like < ::string> to avoid the problem.

Johannes Schaub - litb
jesus christ. this language is getting way trickier everyday (for me)
aaa
+1 Thanks for the explanation! And this digraph stuff is so funny :)
FredOverflow
Do you know what actually leads to that syntax being allowed in the standard? I don't see it at the moment.
Georg Fritzsche
@gf you mean the `f<..>` syntax? It's a template-id, which is a id-expression, which is a declarator-id.
Johannes Schaub - litb
I mean the specialization syntax of `template<> R f(T)` instead of `template<> R f<T>(T)`.
Georg Fritzsche
@gf, See 14.8.1/2 and 14.7.3/11
Johannes Schaub - litb
Ah, i must have had a blind moment when i looked through *§14.7.3*. Thanks :)
Georg Fritzsche
A: 

Additionally, you don't need to specialize in this case, just overload and be happy.

namespace std
{
    void swap(Foo& x, Foo& y)
    {
        x.swap(y);
    }
}
dash-tom-bang
If you like undefined behavior, then yes :) You are not allowed to overload in the `std` namespace.
FredOverflow