0

I have written simple class like below in file VRKVector.h

namespace vrk {
class VRKVector {

private:
    std::vector<int> m_coordinates;
    int              m_dimension;
    
public:
    /** VRKVector constructor.
      * @param coordinates which represents a vector coordinates.
      * @return none.
    */
    VRKVector(std::vector<int> coordinates);

    /** operator << : output stream operator
      * @param out which is output stream we want to write
      * @param vector which represents a vector coordinates.
      * @return none.
    */
    friend std::ostream& operator << (std::ostream& out, vrk::VRKVector& vrkvector);

    };
}

VRKVector.cpp

// ============================================================================
// Local includes, e.g. files in the same folder, typically corresponding declarations.
#include "VRKVector.h"


// ============================================================================
// System includes, e.g. STL.
#include <iostream>
#include <fstream>
#include <sstream> 
#include <iterator>
#include <algorithm>




// namespace declarations;
using namespace std;
using namespace vrk;

VRKVector::VRKVector(std::vector<int> coordinates) {
    m_coordinates = coordinates;
    m_dimension = coordinates.size();
}


std::ostream& operator<< (std::ostream& out, vrk::VRKVector& vrkvector) {
    out << vrkvector.m_dimension;
    return out; // return std::ostream so we can chain calls to operator<<
}

Above code I am getting error as shown below

1>C:\VRKVector.cpp(42,18): error C2248: 'vrk::VRKVector::m_dimension': cannot access private member declared in class 'vrk::VRKVector'
1>C:\\VRKVector.h(40): message : see declaration of 'vrk::VRKVector::m_dimension'

We can assess private member as we have friend function. Why am I seeing the error?

Jason Aller
  • 3,541
  • 28
  • 38
  • 38
venkysmarty
  • 11,099
  • 25
  • 101
  • 184
  • wrong namespace. You friended `std::ostream& vrk::operator << (std::ostream& out, vrk::VRKVector& vrkvector);` and defined `std::ostream& ::operator << (std::ostream& out, vrk::VRKVector& vrkvector);` (global scope). – Marek R Jul 15 '20 at 12:49
  • Here is fixed [mcve] https://godbolt.org/z/neTnEs – Marek R Jul 15 '20 at 12:55

2 Answers2

2

You need to define the operator<< in the namespace vrk, the friend declaration declares it as the member of the namespace vrk.

A name first declared in a friend declaration within a class or class template X becomes a member of the innermost enclosing namespace of X, ...

std::ostream& vrk::operator<< (std::ostream& out, vrk::VRKVector& vrkvector) {
//            ^^^^^
    out << vrkvector.m_dimension;
    return out; // return std::ostream so we can chain calls to operator<<
}
songyuanyao
  • 169,198
  • 16
  • 310
  • 405
1
std::ostream& operator<< (std::ostream& out, vrk::VRKVector& vrkvector){} 

Is not the definition of

friend std::ostream &operator<<(std::ostream &out, vrk::VRKVector &vrkvector);

As it's in a different namespace, it can't access the private class member as is to be expected, a global function can't access a given class private members.

You can fix it by using one of the following options:

  • Defining it inline:
friend std::ostream &operator<<(std::ostream &out, vrk::VRKVector &vrkvector){
    out << vrkvector.m_dimension;
    return out; // return std::ostream so we can chain calls to operator<<
}
  • Defining it inside the namespace.

  • Using namespace scope:

std::ostream& vrk::operator<< (std::ostream& out, vrk::VRKVector& vrkvector) { 
    /*...*/
}
anastaciu
  • 23,467
  • 7
  • 28
  • 53