user1884814
user1884814

Reputation: 31

Friend function can't access class variables and can't understand Namespaces

I thought that friend functions could access class variables as in how I try to do v.x, v.y, v.z in the << function. But it doesn't compile. It says it's unable to resolve identifier at those lines.

Also I'm trying to learn how to use namespaces. Even though I use the namespace vec in the implementation file I still have to include Vector:: before everything so what's the point?

Header file:

#ifndef VECTOR_H
#define VECTOR_H

namespace vec {

    class Vector {
    private:
        double x, y, z;

    public:
        Vector(double, double, double);
        friend std::ostream& operator<<(std::ostream&,  const Vector&);

    };

}

#endif  /* VECTOR_H */

.cpp file:

#include "Vector.h"
#include <iostream> 
using namespace vec;

//Constructor
Vector::Vector(double x1 = 0, double y1 = 0, double z1 = 0) {
    x = x1;
    y = y1;
    z = z1;
}

//Have also tried adding vec:: and Vector:: before operator<< here.
std::ostream& operator<<(std::ostream& out, const Vector& v) {
    out<<"<"<<v.x<<", "<<v.y<<", "<<v.z<<">";
    return out;
}

Upvotes: 1

Views: 861

Answers (3)

billz
billz

Reputation: 45470

Your compile error may relative to below issues:

  • Default parameter only goes to function declaration not function definition, you are doing the other way around.
  • Also, in Vector.cpp you should wrap up your class member function definitions in namespace instead of calling using directive.

Try:

Vector.h

#include <iostream>
class Vector {
    private:
        double x, y, z;

    public:
        Vector(double x1 = 0, double y1 = 0, double z1 = 0);
                        ^^              ^^             ^^
        friend std::ostream& operator<<(std::ostream&,  const Vector&);

    };

Vector.cpp

namespace vec
{
   Vector::Vector(double x1, double y1, double z1)
   :x(x1), y(y1), z(z1)
   {
   }
}

Upvotes: 1

Mats Petersson
Mats Petersson

Reputation: 129524

I believe part of the problem is that your vec.h doesn't have #include <iostream>, so the type std::ostream is unidentified in that file, and since that part is compiled before the vec.cpp main part, it fails to recognise your function.

You also need to put your operator<< into the namespace of vec. After all, you have asked for a friend function within that namespace.

With these two changes, your code compiles with gcc -Wall -Wextra -O2.

Upvotes: 1

Tony Delroy
Tony Delroy

Reputation: 106244

The friend std::ostream& operator<< declaration appears in namespace vec, so the definition should be prefixed by vec::. Your comment says you tried that - maybe you got confused by the other error messages billz documents, but you should reinstate vec::operator<< or surround it with namespace vec { ... }.

This creates an error like:

ns.cc: In function `int main()':
ns.cc:26: error: ambiguous overload for 'operator<<' in 'std::cout << w'
ns.cc:19: note: candidates are: std::ostream& operator<<(std::ostream&, const vec::Vec&)
ns.cc:10: note:                 std::ostream& vec::operator<<(std::ostream&, const vec::Vec&)

Upvotes: 0

Related Questions