Hello--

Inside of a header file (Point.h), I've created a class template. I need to override the addition operator as shown below, so what I have done is declared it as a friend. However, when I try to access the private member variable std::vector<T>coord from within the body of the overloaded function, the compiler complains with the following error:

'std::vector<double, std::allocator<double> > Point<double>::coord' is private

Must I make the member variable std::vector<T>coord public, or can I keep it private with a small modification of my code? Here is a snippet from the Point.h file demonstrating the issue.

template <class T>
class Point
{
public:
   Point();
   template <class U>
   friend const Point<U> operator+(const U &lhs, const Point<U> &rhs);
private:
std::vector<T> coord;
};

template <class T> Point<T>::Point()
{   }

template <class U> const Point<U> operator+(const U &lhs, Point<U> &rhs)
{
   rhs.coord[0] = 1;  // ERROR occurs here
return rhs;
}

Dani AI

Generated

Nice catch, — the compiler message about coord being private comes from a signature mismatch: the friend declaration inside the class must exactly match the non‑member function you later define (including const qualifiers and reference-ness). If they differ, the function you define is not the friend you declared, so it cannot access private members.

Two practical, safer patterns to avoid this class of bug:

  • Prefer not to mutate arguments in operator+. Make a copy (or take by value) and return a plain (non-const) value. Declaring the operator inline as a friend that takes the right-hand operand by value lets you modify the copy and return it:
friend Point operator+(const T& lhs, Point rhs) {
    // modify rhs (a copy) and return it
    return rhs;
}
  • Implement operator+= as a member (it has access to privates), then implement operator+ as a non-member wrapper that reuses operator+=:
Point& operator+=(const T& v) { /* update internals */ return *this; }

friend Point operator+(Point lhs, const Point& rhs) { lhs += rhs; return lhs; }

Extra notes: avoid returning const Point by value — it is almost never useful and can prevent moves/assignments. If you keep a separate friend declaration and out-of-class definition, double-check every qualifier and template parameter so the signatures match exactly. Finally, consider exposing a minimal public API (or operator+=) instead of making many friends; that keeps encapsulation cleaner and reduces similar mistakes.

Oh no--my mistake! All that is required is indeed a small change. This line must be modified:

friend const Point<U> operator+(const U &lhs, const Point<U> &rhs);

Here is the modification:

friend const Point<U> operator+(const U &lhs, Point<U> &rhs);

It's one of these things where you have seen the code again and again, and can't see the forest for the rest of the trees.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.