Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the right way to write friend function declarations in template class?

I'm trying to write my own vector template class, but I have some problems when writing friend function declarations.

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 reports a warning that I declare a non-template function. So I changed the friend 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 everything is fine, but I think there are still problems. If I write like that, I make all operator== functions which take two template arguments as its friend functions. For example, operator==(const vector<int>&, const vector<int>&) and operator==(const vector<double>&, const vector<double>&) would both be vector<int>'s friend function.

What is the right way to write friend functions in template class?

like image 265
Marvis Lu Avatar asked Apr 29 '17 13:04

Marvis Lu


People also ask

How do you declare a friend function in class?

A function or class can't declare itself as a friend of any class. In a class definition, use the friend keyword and the name of a non-member function or other class to grant it access to the private and protected members of your class. In a template definition, a type parameter can be declared as a friend .

Which one is the correct syntax to declare the friend function?

2. Which keyword is used to declare the friend function? Explanation: friend keyword is used to declare a friend function in C++.

Where we should declare a function as a friend to a?

friend Function in C++ A friend function can access the private and protected data of a class. We declare a friend function using the friend keyword inside the body of the class.

What is a friend function and how you declare it?

A friend function in C++ is defined as a function that can access private, protected and public members of a class. The friend function is declared using the friend keyword inside the body of the class. Friend Function Syntax: class className { ... .. ... friend returnType functionName(arguments); ... .. ... }


1 Answers

Friend non-template function

But the compiler reports a warning that I declare a non-template function.

Yes, you're declaring a non-template function inside the class definition. That means if you define it out of the class definition, you have to define it as non-template function, and for all the possible instantiations , like:

bool operator==(const vector<int>& v1, const vector<int>& v2)
{
    ...
}
bool operator==(const vector<char>& v1, const vector<char>& v2)
{
    ...
}

That is ugly, you can define it inside the 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 template function, and constrain 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 friend, other instantiations like bool operator==(const vector<double>&, const vector<double>&) is not.

LIVE

like image 72
songyuanyao Avatar answered Oct 25 '22 01:10

songyuanyao