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.
I believe that this is what you want (which happens to be what you just added to your question as the third option)
#include <utility>
template <typename T> class node;
template <typename T> void swap(node<T> & a, node<T> & b);
template<typename T> class node {
private:
node<T>* left;
node<T>* right;
T value;
public:
friend void swap<>(node<T>&, node<T>&);
};
template <typename T> void swap(node<T> & a, node<T> & b) {
std::swap(a.left, b.left);
std::swap(a.right, b.right);
std::swap(a.value, b.value);
}
int main() {
node<int> x, y;
swap(x, y);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With