What is the correct way to write friend function declarations in template class?
I am trying to write my own vector template template, but I have some problems while writing a friend's function declaration.
At first I wrote like this:
template <typename T, typename Alloc = std::allocator<T>>
class vector {
public:
friend bool operator==(const vector<T, Alloc>&, const vector<T, Alloc>&);
};
But the compiler is giving a warning that I am declaring a function without a template. So I changed my friend's declaration to this:
template <typename T, typename Alloc = std::allocator<T>>
class vector {
public:
template <typename E, typename F>
friend bool operator==(const vector<E, F>&, const vector<E, F>&);
};
So far so good, but I think there are still problems. If I write like this, I make all operator==
functions that take two template arguments as their friend functions. For example, operator==(const vector<int>&, const vector<int>&)
and operator==(const vector<double>&, const vector<double>&)
would be vector<int>
a friend function.
What is the correct way to write friend functions in a template class?
source to share
Function friendly without template
But the compiler gives a warning that I am declaring a function without a template.
Yes, you are declaring a function without a template inside a class definition. This means that if you define it from a class definition, you must define it as a function without a template and for all possible instances, for example:
bool operator==(const vector<int>& v1, const vector<int>& v2)
{
...
}
bool operator==(const vector<char>& v1, const vector<char>& v2)
{
...
}
It's ugly, you can define it inside a class definition like
template <typename T, typename Alloc = std::allocator<T>>
class vector {
public:
friend bool operator==(const vector<T, Alloc>&, const vector<T, Alloc>&) {
...
}
};
Friend function template
If you want to define it as a template function and limit the scope of friendship, you can
// forward declaration
template <typename T, typename Alloc>
class vector;
// forward declaration
template <typename T, typename Alloc>
bool operator==(const vector<T, Alloc>& v1, const vector<T, Alloc>& v2);
template <typename T, typename Alloc = std::allocator<T>>
class vector {
private:
int i;
public:
// only the instantiation of operator== with template parameter type of current T and Alloc becomes friend
friend bool operator==<>(const vector<T, Alloc>& v1, const vector<T, Alloc>& v2);
};
template <typename T, typename Alloc = std::allocator<T>>
bool operator==(const vector<T, Alloc>& v1, const vector<T, Alloc>& v2)
{
...
}
Then for vector<int>
only bool operator==(const vector<int>&, const vector<int>&)
is a friend, other instances bool operator==(const vector<double>&, const vector<double>&)
are not like .
source to share