Accessing private variables in friend methods from a class that is inside a namespace

Below is the sample code that illustrates my problem.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#include <iostream>
#include <ostream>

using namespace std;

namespace test
{
class Test
{
    int x;
public:
    Test(int n) : x(n) {}

    friend ostream& operator<< (ostream& os, const Test t);
};

}

using namespace test;
ostream& operator<< (ostream& os, const Test t)
{
    os << t.x;
    return os;
}

int main()
{
    Test g(3);

    cout << g;


    return 0;
}  


The programs throws the following error:
error: 'int test::Test::x' is private within this context|

I have to put the class inside a namespace, it has to contain the operator<< overload and the variable must be private but I can't seem to get it working.

The compiled is compiled in GCC 9.2.0, codeblocks, windows 10.

Any help?
Thanks
Hello hbcpp,

You are learning about name spaces, so now is the time to learn how to qualify what is in a name space be it "std::" or "test::". Stop relaying on the "using" statements.

Line 19 is not working the way that you are thinking is should. This does work for line 28.

In the following code there are two options. I suggest learning to use the first option as it will serve you better in the long run.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
#include <iostream>
//#include <ostream> // <--- included in "iostream".

//using namespace std;  // <--- Best not to use.
// The most recent post that is worth reading. http://www.cplusplus.com/forum/beginner/258335/


namespace test
{
	class Test
	{
			int x;
		public:
			Test(int n) : x(n) {}

			friend std::ostream& operator<< (std::ostream& os, const Test t);
	};

}

std::ostream& test::operator<< (std::ostream& os, const Test t) // <--- Option 1. Better choice.
{
	os << t.x;
	return os;
}

namespace test // <--- Option 2.
{
	std::ostream& operator<< (std::ostream& os, const Test t)
	{
		os << t.x;
		return os;
	}
}

//using namespace test;

int main()
{
	//Test g(3);
	test::Test g(3); // <--- Better choice.
	std::cout << g;


	return 0;  // <--- Not required, but makes a good break point.
}

Choose option 1 or 2. It will not compile if you leave both. Either one works when tested with VS2017.

Since you put the class in a name space the functions defined outside the class either need to be qualified or put in the same name space.

Andy
Hi Andy

It works, thank you very much.

But why exactly the choice 1 is better than the choice 2.

For me the choice 2 makes the code less verbose, it is quicker to use as choice 1 seems to be more readable and makes the code cleaner and clearer I think.
Hello hbcpp,

Because now that yo are learning about "name spaces" it is a good idea to learn how to qualify what is in a "name space" be it a "name space" that you define or what is in the "standard" namespace.

Given the line using namespace std; may seem to be easy to use right now, but some day it will cause you a problem. Whom ever taught you about this using statement is just lazy or the course was designed to to teach name spaces much later than it should be.

There may be times when splitting something in a name space that you define into two files it may be better to use option 2 to make everything work.

If you feel more comfortable using option 2 then do so. It is better to understand what you are doing first.

Andy
Actually you should be putting the function inside the same namespace as in choice 2, or place the implementation directly within the class.

Choice 1 should fail to compile, from the online compiler:
21:63: error: 'std::ostream& test::operator<<(std::ostream&, test::Test)' should have been declared inside 'test'
Noted Andy, thanks guys for the help, really appreciated it.
Topic archived. No new replies allowed.