2

I'm writing a simple data structure for a tree.

I have these classes:


//declaration of tree_pos_vector
template<class T> 
class tree_pos_vector;
template<class T>
class node{
private: 
    int pos;
    int num_children;
    /*other member and function
    ...
    */

public: 
    /*other function
     ....
    */
     template<class W> friend class tree_pos_vector;

    friend std::ostream& operator<<(std::ostream &os,tree_pos_vector<T>& _tree);
}
template<class T>
class tree_pos_vector{
private:
    std::vector<node<T>*> vec_node;
    /*other member and function
    ...
    */

public: 

    /*other function
    ...
    */

    friend std::ostream& operator<<(std::ostream &os,tree_pos_vector<T>& _tree){
        for(auto &n: _tree.vec_node){
                for(int i=0;i < n->num_children; i++){
                    os<< "( "<<*n<<","<< vec_node[n->pos*degree+i] << ")\n";
                }
        }
    }
}

The problem is that the members n->num_children and n->pos remains private and I cannot access them from this function.

Where is the problem?

There is a way to access to private member of node from operator<< function?

flowibbia
  • 21
  • 3
  • 2
    There are two solutions: 1st) make the `operator<<` for `tree_pos_vector` a friend of `node`. 2nd) Add a wrapper function to `tree_pos_vector` which let friends of `tree_pos_vector` access private details of `node`. I would prefer: 3rd) make `const` functions to expose private details of classes but read-only. In this case, no friend-ship is needed for output. (Oh, I must admit there are _three_ solutions...) – Scheff's Cat Sep 28 '21 at 07:53
  • 1
    Add (private) member functions to `tree_pos_vector` that accept a `node` and return its `num_children` and `pos`. – n. m. could be an AI Sep 28 '21 at 07:53
  • 2
    @Scheff'sCat I like to add a fourth ;) Access data through interfaces (abstract bases) defined in namespace details. These interfaces will have private implementation ensuring "normal" clients don't get to the methods directly https://onlinegdb.com/eYo4VocRx. (Ok this is me playing around with interfaces, I like them because they can be used to model use, which class can get to what) – Pepijn Kramer Sep 28 '21 at 09:09

1 Answers1

1

You should define the operator<< for tree_pos_vector outside of the class, and only leave the declaration inside (see here for a working example. Beware, though, that the code you've given in your question had several other flaws that I had to fix there, and my solutions might not have been what you wanted them to. In short, try not to copy-paste the example blindly).

As far as I'm aware, it happens because friend operators defined inside class bodies are invisible to normal lookup, and can only be detected by ADL, but I couldn't find an explicit mention of this on cppreference. (I have just searched again to check, and have found a mention of this on stackoverflow. You should start there, if you're interested in the exact details).

abel1502
  • 955
  • 4
  • 14