I was trying to compile the following code for the classic copy&swap idiom on my Mac with clang 3.3
template<typename T> class node{
private:
node<T>* left;
node<T>* right;
T value;
public:
friend void swap(node<T>&, node<T>&);
// other stuff
}
Yet the linker complained. I now understand that I should declare the function as a template. But error would occur if I follow the style as suggested here from MSDN:
template <class T> class Array {
T* array;
int size;
public:template<class T>
//...
template <class T>
friend Array<T>* combine(Array<T>& a1, Array<T>& a2);
};
I did copy-paste but got the following error:
te.cpp:33:19: error: declaration of 'T' shadows template parameter
template<class T>
^
te.cpp:4:17: note: template parameter is declared here
template <class T> class Array {
^
1 error generated.
Is this a clang bug? The MSDN website suggests it works under VC++.
PS: I know that there are two solutions: define the friend function inside the template class as in the Stackoverflow article, or declare in the following way inside the template class:
template <typename U> friend void swap(node<U>&, node<U>&);
But both bother me. The first clusters the declaration of the class while the second grants friendship to swap taking different types.
Update: A third solution is to use forward declaration with specialization:
template <typename T> class node;
template <typename T> void swap (node<T>&, node<T>&);
template <typename T> class node{
//...
friend void swap<> (node<T>&, node<T>&);
};
This works under clang too.
See Question&Answers more detail:os