Friend isn't friendly

Started by
2 comments, last by SiCrane 15 years, 3 months ago
I have some code where I am overloading the insertion and extraction operators. Even though I have declared both overloaded operators to be friends of my class I am getting an exception saying that the overloaded operator doesn't have access to private members of my class. Start.h
[source lang=cpp]
#ifndef IGES_SECTION_START_H_
#define IGES_SECTION_START_H_

#include <iosfwd>
#include <string>

namespace IGES
{
	namespace Section
	{
		class Start
		{
		public:
			friend std::ostream & operator<<(std::ostream & stream, Start const & start);
			friend std::istream & operator>>(std::istream & stream, Start const & start);
		protected:
		private:
			std::string data;
		};
	};
};

std::ostream & operator<<(std::ostream & stream, IGES::Section::Start const & start);
std::istream & operator>>(std::istream & stream, IGES::Section::Start const & start);

#endif


Start.cpp
[source lang=cpp]
typedef std::map<IGES::Datatype::Integer, std::string> map_type;

std::istream & operator>>(std::istream & stream, IGES::Section::Start const & start)
{
	std::string line;
	map_type lines;
	do
	{
		std::ios_base::streampos startOfLine = stream.tellg();
		std::getline(stream, line);
		if(line[72] == 'S')
		{
			if(line.size() != 80)
			{
				throw new std::invalid_argument("start lines must be 80 charaters long");
			}
			IGES::Datatype::Integer lineNumber = boost::lexical_cast<IGES::Datatype::Integer>(line.c_str() + 72);
			lines.insert(std::make_pair(lineNumber, std::string(line.begin(), line.begin() + 72)));
		}
		else
		{
			stream.seekg(startOfLine);
		}
	}while(line[72] == 'S');
	for(map_type::const_iterator i = lines.begin(); i != lines.end(); ++i)
	{
		start.data.append(i->second);
	}
	return stream;
}

The error is on the line that says: start.data.append(i->second); It says that I can't access private member data of class Start. Am I misusing friend? I very rarely have need of it, so I'm not nearly as familiar with its intricacies as other parts of C++.
Advertisement
The problem is that your friend declarations have friended operator<< and operator>> inside the IGES::Section namespace and your definitions live in the root namespace. The easiest fix would be to put the definitions in the IGES::Section namespace.
Would that solution still allow me to something like:
[source lang=cpp]#include <Start.h>#include <iostream>int main(){    Start s;    std::cin >> s;    return 0;}
Did you try it?

This topic is closed to new replies.

Advertisement