473,701 Members | 2,604 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Friend functions and template classes

Hello, all I'm having a problem with friend functions in a templatized Queue
class I'm writing using linked lists. The problem is that I can't get the
friend function to be able to access private data from the class. Here's
the gist of the code:

template <class T>
struct NodeType
{
T data;
NodeType<T> * link;
};

template <class T>
class Queue1
{
friend ostream & operator<< (ostream & lhs, const Queue1 <T> & rhs);
// some public methods & stuff here
private:
NodeType <T> * head;
NodeType <T> * tail;
};

template <class T>
ostream & operator<< (ostream & lhs, const Queue1 <T> & rhs)
{
NodeType <T> * pIterator = rhs.tail;
return &lhs;
}

The problem I get is that in the operator<< function my compiler (Visual C++
6) is reporting:

'tail' : cannot access private member declared in class 'Queue1<char>'

(this is of course using a driver program that declares a Queue1<char>
object).

Any suggestions would be appreciated.

Adam

Jul 22 '05 #1
6 2333
"Adam Parkin" <sk****@dfaslk. com> wrote...
Hello, all I'm having a problem with friend functions in a templatized Queue class I'm writing using linked lists. The problem is that I can't get the
friend function to be able to access private data from the class. Here's
the gist of the code:

template <class T>
struct NodeType
{
T data;
NodeType<T> * link;
};
I think you need to do a bit of a declaration dance. Put here:

template<class T> class Queue1;
template<class T> ostream& operator <<(ostream&, const Queue1<T>&);
template <class T>
class Queue1
{
friend ostream & operator<< (ostream & lhs, const Queue1 <T> & rhs);
Change this to

friend ostream& operator<< <T>(ostream&, const Queue1&);
// some public methods & stuff here
private:
NodeType <T> * head;
NodeType <T> * tail;
};

template <class T>
ostream & operator<< (ostream & lhs, const Queue1 <T> & rhs)
{
NodeType <T> * pIterator = rhs.tail;
return &lhs;
You probably meant

return lhs;

here. BTW, avoid typing your program directly into a posting.
}

The problem I get is that in the operator<< function my compiler (Visual C++ 6) is reporting:

'tail' : cannot access private member declared in class 'Queue1<char>'

(this is of course using a driver program that declares a Queue1<char>
object).


---------------------------------------------- This code
#include <iostream>
using namespace std;

template <class T>
struct NodeType
{
T data;
NodeType<T> * link;
};

template<class T> class Queue1;
template<class T> ostream& operator <<(ostream&, const Queue1<T>&);

template <class T>
class Queue1
{
friend ostream & operator<< <T>(ostream &, const Queue1&);
// some public methods & stuff here
private:
NodeType <T> * head;
NodeType <T> * tail;
};

template <class T>
ostream & operator<< (ostream & lhs, const Queue1 <T> & rhs)
{
NodeType <T> * pIterator = rhs.tail;
return lhs;
}

int main()
{
Queue1<int> qi;
cout << qi;
return 0;
}

----------------------------------------------
compiles fine with Comeau and Intel. VC++ v6 refuses to compile it (due
to its very poor template handling abilities). A quick solution to this
would be a public member function

ostream& print(ostream& out) const
{
// do what you need
return out;
}

in the Queue1 template. The template output operator would call it:

template<class T> ostream& operator << (ostream& os, const Queue1<T>& t)
{
return t.print(os);
}
------------------------------- Full code that compiles with VC++
#include <iostream>
using namespace std;

template <class T>
struct NodeType
{
T data;
NodeType<T> * link;
};

template <class T>
class Queue1
{
public:
ostream & print(ostream & out) const
{
NodeType<T> *pIt = tail;
return out;
}
// some public methods & stuff here
private:
NodeType <T> * head;
NodeType <T> * tail;
};

template<class T>
ostream & operator<<(ostr eam & lhs, const Queue1<T> & rhs)
{
return rhs.print(lhs);
}

int main()
{
Queue1<int> qi;

cout << qi;

return 0;
}
------------------------------------------------------------
HTH

Victor
Jul 22 '05 #2
Adam Parkin wrote:
[snip]
template <class T>
class Queue1
{
friend ostream & operator<< (ostream & lhs, const Queue1 <T> & rhs);
// some public methods & stuff here
private:
NodeType <T> * head;
NodeType <T> * tail;
};

template <class T>
ostream & operator<< (ostream & lhs, const Queue1 <T> & rhs)
{
NodeType <T> * pIterator = rhs.tail;
return &lhs;
}
As Victor said, changing
friend ostream & operator<< (ostream & lhs, const Queue1 <T> & rhs);
to
friend ostream & operator<< <> (ostream & lhs, const Queue1 <T> & rhs);

(you can write <> instead of <T> here) would solve the problem with the
right compiler. Here is why: your definition of operator<< is a function
template; its friend declaration, if unqualified, must be a template-id
(just what you probably meant to do).

Any suggestions would be appreciated.


0. Get a better compiler.

There are a couple of alternatives that you could try as well.

1. Remember,
friend ostream & operator<< (ostream & lhs, const Queue1 <T> & rhs);

is a declaration of a function, not a function template, despite the <T>
in the argument list. That means that the compiler will need a corresponding
definition. Replace your definition of operator<< with the following
(but keep your original friend declaration):

ostream & operator<< (ostream & lhs, const Queue1 <char> & rhs)
{
NodeType <char> * pIterator = rhs.tail;
return lhs;
}

Note that this is not a template specialisation. I wouldn't like doing it
this way, but it is still standard, and maybe VC++6 will accept it.
2. Finally, you may try the following: qualify the declaration of the friend
operator<< with :: and predeclare it (rules are different for qualified names
in this case):

template <class T>
class Queue1;

template <class T>
ostream & operator<< (ostream & lhs, const Queue1 <T> & rhs);

template <class T>
class Queue1
{
friend ostream & ::operator<< <> (ostream & lhs, const Queue1 <T> & rhs);
// some public methods & stuff here
private:
NodeType <T> * head;
NodeType <T> * tail;
};
Denis
Jul 22 '05 #3
"Denis Remezov" <RE************ *********@yahoo .removethis.ca> wrote...
Adam Parkin wrote:
[snip]

template <class T>
class Queue1
{
friend ostream & operator<< (ostream & lhs, const Queue1 <T> & rhs);
// some public methods & stuff here
private:
NodeType <T> * head;
NodeType <T> * tail;
};

template <class T>
ostream & operator<< (ostream & lhs, const Queue1 <T> & rhs)
{
NodeType <T> * pIterator = rhs.tail;
return &lhs;
}


As Victor said, changing
friend ostream & operator<< (ostream & lhs, const Queue1 <T> & rhs);
to
friend ostream & operator<< <> (ostream & lhs, const Queue1 <T> & rhs);

(you can write <> instead of <T> here) would solve the problem with the
right compiler. Here is why: your definition of operator<< is a function
template; its friend declaration, if unqualified, must be a template-id
(just what you probably meant to do).

Any suggestions would be appreciated.


0. Get a better compiler.

There are a couple of alternatives that you could try as well.

1. Remember,
friend ostream & operator<< (ostream & lhs, const Queue1 <T> & rhs);

is a declaration of a function, not a function template, despite the <T>
in the argument list. That means that the compiler will need a

corresponding definition. Replace your definition of operator<< with the following
(but keep your original friend declaration):

ostream & operator<< (ostream & lhs, const Queue1 <char> & rhs)
{
NodeType <char> * pIterator = rhs.tail;
return lhs;
}

Note that this is not a template specialisation. I wouldn't like doing it
this way, but it is still standard, and maybe VC++6 will accept it.
2. Finally, you may try the following: qualify the declaration of the friend operator<< with :: and predeclare it (rules are different for qualified names in this case):

template <class T>
class Queue1;

template <class T>
ostream & operator<< (ostream & lhs, const Queue1 <T> & rhs);

template <class T>
class Queue1
{
friend ostream & ::operator<< <> (ostream & lhs, const Queue1 <T> & rhs);
VC++ chokes on this. I gave a solution, and of course, your option 0
is just fine too.

Victor
// some public methods & stuff here
private:
NodeType <T> * head;
NodeType <T> * tail;
};
Denis

Jul 22 '05 #4
"Denis Remezov" <RE************ *********@yahoo .removethis.ca> wrote in
message news:40******** *******@yahoo.r emovethis.ca...
As Victor said, changing
friend ostream & operator<< (ostream & lhs, const Queue1 <T> & rhs);
to
friend ostream & operator<< <> (ostream & lhs, const Queue1 <T> & rhs);

(you can write <> instead of <T> here) would solve the problem with the
right compiler.
And of course VC6 is not the right compiler, as this doesn't work.
Any suggestions would be appreciated.


0. Get a better compiler.


LOL, thanks. :-p
is a declaration of a function, not a function template, despite the <T>
in the argument list. That means that the compiler will need a corresponding definition. Replace your definition of operator<< with the following
(but keep your original friend declaration):

ostream & operator<< (ostream & lhs, const Queue1 <char> & rhs)
{
Hehe, funny enough, VC6 reports this as "binary '<<' : no operator defined
which takes a right-hand operand of type 'class Queue1<char>' (or there is
no acceptable conversion)", even though I've explicitly included the <char>
in my function definition.

2. Finally, you may try the following: qualify the declaration of the friend operator<< with :: and predeclare it (rules are different for qualified names in this case):

template <class T>
class Queue1;

template <class T>
ostream & operator<< (ostream & lhs, const Queue1 <T> & rhs);


Yeah, I actually found this code on a few websites, but no, it doesn't work
under VC6 (or at least didn't for me). Thanks for the help.

Adam
Jul 22 '05 #5
"Victor Bazarov" <v.********@com Acast.net> wrote in message
news:c4_hc.4892 $0u6.1057800@at tbi_s03...
"Adam Parkin" <sk****@dfaslk. com> wrote...
Hello, all I'm having a problem with friend functions in a templatized

Queue
class I'm writing using linked lists. The problem is that I can't get the friend function to be able to access private data from the class. Here's the gist of the code:


Okay, figured out the problem, although I'm not entirely sure why it caused
a problem. My driver.cpp had:

#include "queue1.h"
#include <iostream>
using namespace std;

in it, and once I changed this to:

#include "queue1.h"
#include <iostream>
using std::cout;
using std::endl;

Everything worked fine, as the access of the private data member in
operator<< was now legal. Can somebody explain why changes in one module
(the Queue1.h file) were affected the way they were by the driver.cpp file?
Is it that there's something in the std namespace which conflicted with my
Queue1 module?

I suppose this is a lesson in don't be lazy, use scope resolution to be as
precise as possible.

Adam
Jul 22 '05 #6
"Adam Parkin" <sk****@dfaslk. com> wrote...
"Victor Bazarov" <v.********@com Acast.net> wrote in message
news:c4_hc.4892 $0u6.1057800@at tbi_s03...
"Adam Parkin" <sk****@dfaslk. com> wrote...
Hello, all I'm having a problem with friend functions in a templatized Queue
class I'm writing using linked lists. The problem is that I can't get the friend function to be able to access private data from the class. Here's the gist of the code:


Okay, figured out the problem, although I'm not entirely sure why it

caused a problem. My driver.cpp had:

#include "queue1.h"
#include <iostream>
using namespace std;

in it, and once I changed this to:

#include "queue1.h"
#include <iostream>
using std::cout;
using std::endl;

Everything worked fine, as the access of the private data member in
operator<< was now legal. Can somebody explain why changes in one module
(the Queue1.h file) were affected the way they were by the driver.cpp file? Is it that there's something in the std namespace which conflicted with my
Queue1 module?

I suppose this is a lesson in don't be lazy, use scope resolution to be as
precise as possible.


I don't have an answer to your question about the namespace and the
effect of it for the code, but I recommend asking the same question
in microsoft.publi c.vc.language. Of course, keep in mind that they
have been enjoying VC++ .NET probably longer on average than we here,
so they may be tempted to simply say, "it's fixed in v7.1, so get it
and the problem will go away"...

Victor
Jul 22 '05 #7

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

5
2022
by: Ales DOLECEK | last post by:
Hello, I'm trying to created base class and template for "smart" pointer pointing to it. It should do simple reference counting and clean up when the reference count reaches zero. The header looks like this: class base_t { int _ref_count; public: base_t(void): _ref_count(0) {};
21
8585
by: Sebastian Faust | last post by:
Hi, is a construction like the following possible: template<class view_model> class template_clase { protected: template_clase() {} virtual ~template_clase() {}
2
10159
by: Christophe Barbe | last post by:
I posted a few days ago about the same problem but was not very clear. So here is my second take at it. Basically with GCC 3.3.2, I can't compile the example from the C++ FAQ Lite available online at http://www.parashift.com/c++-faq-lite/containers-and-templates.html#faq-34.15 Below are the two files that I compile with g++ foo.cpp -o foo or
5
2715
by: Trevor Lango | last post by:
What is the appropriate syntax for placing a friend function that includes as one of it's parameters a pointer to the class object itself within the template class? I have the following: //**************************************************** // testClass.h //**************************************************** #ifndef TESTCLASS_H
5
2636
by: Ruben Campos | last post by:
Some questions about this code: template <typename T> class MyTemplate; template <typename T> MyTemplate <T> operator- (const MyTemplate <T> & object); template <typename T> MyTemplate <T> operator- (const MyTemplate <T> & object1, const MyTemplate <T> & object2); template <typename T> class MyTemplate
15
6581
by: Samee Zahur | last post by:
Question: How do friend functions and static member functions differ in terms of functionality? I mean, neither necessarily needs an object of the class to be created before they are called and either has access only to static members of the class (ie. assuming no object of the class is in scope - neither by arguments recieved nor by local declarations). Any static member function like this: //accessing static member i static void...
3
1480
by: Pierre Barbier de Reuille | last post by:
Hi, after reading the article " The Standard Librarian : Defining Iterators and Const Iterators" from Matt Austern: http://www.ddj.com/showArticle.jhtml;jsessionid=41JODBZDWEMBYQSNDLOSKH0CJUNN2JVN?articleID=184401331 I wanted to test using the non-template function friends of template classes. So I devised this code: ===8<======8<======8<======8<======8<======8<======8<===
21
4736
by: H9XLrv5oXVNvHiUI | last post by:
Hi, I have a question about injecting friend functions within template classes. My question is specific to gcc (version 3.4.5) used in combination with mingw because this code (or at least code that gets the same result) works as expected in visualc++. I know that this is probably not the right behavior for a compiler but it's the kind of behavior I'm searching for so I was hoping there was a way to do the same thing in gcc. As you know...
3
1722
by: mojmir | last post by:
hello, i have problem with following code (see below). compiler (vs2005sp1) complains that the call to fn is ambiguous: error C2668: 'BB::fn' : ambiguous call to overloaded function could be 'void BB::fn<dummy>(T &,BB::foo &)' or 'void AA::fn<dummy>(T &,BB::foo &)' okay, i have said, and tried to be more specific about the namespace
0
8736
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
9229
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
9083
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
1
8977
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
7824
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
0
5904
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
4410
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
0
4662
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
2
2398
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.