Search code examples
c++classsearchstdvectorfriend

How do I use a private variable in a class through a function(not in any class)?


A function has 2 arguments. One type is a vector of class(has a string private variable). The other is the string it looks for. I tried == both string but it won't work. I expected it but was hoping I could use a friend on it but it appears to work only for 2 classes.

I tried searching up using a friend function on class Term, but couldn't find results that used one class and one function. Besides friend, I can't think of another way.

class Term
{
    string str;
    unsigned long long int weight;
    Term(string s, long int w) : str(s), weight(w) {}
};
//my teacher provided this code so I can't change anything above

int FindFirstMatch(vector<Term> & records, string prefix)
//prefix is the word it looks for and returns the earliest time it appears.
{
    for (int i=0; i<records.size(); i++)
    {
        if (records[i].str==prefix)
        {
//I just need to get this part working
           return i;
        }
    }
}`

It says str is a private member of Term. Which is why I was hoping to simply use a friend on it.


Solution

  • All the members of the Term class is under private custody and hence you can not even make an instance out of it. Your teacher definitely missed/ or want you to figure it out this.

    Other than friending the member, you could provide a getter function by which you will able to access it.

    class Term
    {
    private:
        std::string _str;
        unsigned long long int weight;
    
    public:
        // constructor needs to be public in order to make an instance of the class
        Term(const std::string &s, long int w) : _str(s), weight(w) {}
    
        // provide a getter for member string
        const std::string& getString() const /* noexcept */ { return _str; }
    };
    
    int FindFirstMatch(const std::vector<Term>& records, const std::string &prefix)
    {
        for (std::size_t i = 0; i < records.size(); i++)
        {
            if (records[i].getString() == prefix) // now you could access via getString()
            {
                return i;
            }
        }   
        return -1; // default return
    }
    

    Or if you are allowed to use standard algorithms, for instance using std::find_if and std::distance.

    (See Live)

    #include <iterator>
    #include <algorithm>
    
    int FindFirstMatch(const std::vector<Term>& records, const std::string &prefix)
    {
        const auto iter = std::find_if(std::cbegin(records), std::cend(records), [&](const Term & term) { return term.getString() == prefix; });
        return iter != std::cend(records) ? std::distance(std::cbegin(records) , iter) : -1;
    }