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?

+3


source to share


1 answer


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 .

LIVE

+4


source







All Articles