473,657 Members | 2,434 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Confused about friends in template class

According to:
http://www.parashift.com/c++-faq-lit....html#faq-35.4
, if my understanding is correct, in

template<typena me T>
class Foo {
friend void func (const Foo<T>& foo);
};

template<typena me T>
void func (const Foo<T>& foo) { ... }

func is seen as a non-template function at class instantation time,
and the func function template is never actually instantieted, so the
linker error (the compiler is searching the ordinary one).

The proposed solution is via forward declaration, but (in VC 8) this
works:

template<typena me T>
class Foo {

template<typena me T>
friend void func (const Foo<T>& foo);
};

template<typena me T>
void func (const Foo<T>& foo) { ... }
However gcc complains about the fact that T (of func) shadows T (of
Foo), but the following works:

template<typena me T>
class Foo {

template<typena me U>
friend void func (const Foo<U>& foo);
};

template<typena me T// Or U, indifferent right?
friend void func (const Foo<T>& foo);

According to a book of mine (maybe outdated, 2002) it seems that the
difference between this last option and the one proposed in the guide
is that here func can be a friend of classes with different templates,
like:
func<Afriend of Foo<B>
while in the solution proposed in the guide this can not happend.

My intuition (probably wrong) is than that the "invalid VC syntax"
really means to the VC compiler the situation illustrated in the guide
via forward declaration, but this syntax is illegal according to the
standard.
Too bad, I liked this more concise solution :)

Anyway, if my understanding was correct, there are reasons to avoid
using always the last option, where the function is also a friend of
instantation of the class with different parameters?

Cheers
StephQ

May 16 '07 #1
4 1904
StephQ wrote:
According to:
http://www.parashift.com/c++-faq-lit....html#faq-35.4
, if my understanding is correct, in

template<typena me T>
class Foo {
friend void func (const Foo<T>& foo);
};
You declared a non-template function func here...
>
template<typena me T>
void func (const Foo<T>& foo) { ... }

func is seen as a non-template function at class instantation time,
and the func function template is never actually instantieted, so the
linker error (the compiler is searching the ordinary one).
And the compiler couldn't find a non-template function func to
instantiate Foo...What's confusing you?
>
The proposed solution is via forward declaration, but (in VC 8) this
works:

template<typena me T>
class Foo {

template<typena me T>
friend void func (const Foo<T>& foo);
};

template<typena me T>
void func (const Foo<T>& foo) { ... }
However gcc complains about the fact that T (of func) shadows T (of
Foo), but the following works:

template<typena me T>
class Foo {

template<typena me U>
friend void func (const Foo<U>& foo);
};

template<typena me T// Or U, indifferent right?
friend void func (const Foo<T>& foo);

According to a book of mine (maybe outdated, 2002) it seems that the
difference between this last option and the one proposed in the guide
is that here func can be a friend of classes with different templates,
like:
func<Afriend of Foo<B>
while in the solution proposed in the guide this can not happend.

My intuition (probably wrong) is than that the "invalid VC syntax"
really means to the VC compiler the situation illustrated in the guide
via forward declaration, but this syntax is illegal according to the
standard.
Too bad, I liked this more concise solution :)
It's concise but it's illogical and wrong, even though it may appear
convenient.
>
Anyway, if my understanding was correct, there are reasons to avoid
using always the last option, where the function is also a friend of
instantation of the class with different parameters?
I couldn't think of any reason to avoid using it.
>
Cheers
StephQ
May 16 '07 #2
And the compiler couldn't find a non-template function func to
instantiate Foo...What's confusing you?
Here i just wanted to check if I understood the explanation correctly.
It seemes this is the case :)
It's concise but it's illogical and wrong, even though it may appear
convenient.
Could expand the explanation a little more?
Is it wrong according to the standard? There is a particular reason
for that?
I couldn't think of any reason to avoid using it.
Perfect.

Thank you for you reply.

Cheers
StephQ

May 17 '07 #3
StephQ wrote:
>And the compiler couldn't find a non-template function func to
instantiate Foo...What's confusing you?

Here i just wanted to check if I understood the explanation correctly.
It seemes this is the case :)
>It's concise but it's illogical and wrong, even though it may appear
convenient.

Could expand the explanation a little more?
Is it wrong according to the standard? There is a particular reason
for that?
template<typena me T>
class Foo {
public:
template<typena me T>
friend void func (const Foo<T>& foo);
};

What's the point of declaring template <typename Tfor func? It gets
the template parameter by the function signature, i.e the argument. func
will be instantiated based on Foo's template paramter T. This is why you
are getting complaints from gcc. No need for standard to understand that
this is an dubious declaration. Once you remove the function template
declaration, you create a binding that for any instance of Foo<T>, there
must be a func<Tdefinitio n that completes it unless it's never used
anywhere (but that's not the point here).

It's an completely different story when you say:
template<typena me T>
class Foo {
public:
template<typena me U>
friend void func (const Foo<U>& foo);
};

Here you U and T are orthogonal and Foo<Tand func<Uare too. You
don't create any binding between these two definitions (sort of, when
you invoke func, its template argument type is determined by its
argument). This is a common way to get different template instantiations
to work together. Not in this particular example, but for this one:
template <typename T>
class Foo {
public:
template<typena me U>
Foo<T>& func (const Foo<U>& foo);
};

Foo<intfi;
Foo<floatff;
ff.func(fi);

A common use is to write copy constructors this way to convert between
different template instantation of types.
>I couldn't think of any reason to avoid using it.

Perfect.

Thank you for you reply.

Cheers
StephQ
May 17 '07 #4
On May 17, 11:26 pm, Fei Liu <fei...@aepnetw orks.comwrote:
StephQ wrote:
And the compiler couldn't find a non-template function func to
instantiate Foo...What's confusing you?
Here i just wanted to check if I understood the explanation correctly.
It seemes this is the case :)
It's concise but it's illogical and wrong, even though it may appear
convenient.
Could expand the explanation a little more?
Is it wrong according to the standard? There is a particular reason
for that?

template<typena me T>
class Foo {
public:
template<typena me T>
friend void func (const Foo<T>& foo);

};

What's the point of declaring template <typename Tfor func? It gets
the template parameter by the function signature, i.e the argument. func
will be instantiated based on Foo's template paramter T. This is why you
are getting complaints from gcc. No need for standard to understand that
this is an dubious declaration. Once you remove the function template
declaration, you create a binding that for any instance of Foo<T>, there
must be a func<Tdefinitio n that completes it unless it's never used
anywhere (but that's not the point here).

It's an completely different story when you say:
template<typena me T>
class Foo {
public:
template<typena me U>
friend void func (const Foo<U>& foo);

};

Here you U and T are orthogonal and Foo<Tand func<Uare too. You
don't create any binding between these two definitions (sort of, when
you invoke func, its template argument type is determined by its
argument). This is a common way to get different template instantiations
to work together. Not in this particular example, but for this one:
template <typename T>
class Foo {
public:
template<typena me U>
Foo<T>& func (const Foo<U>& foo);

};

Foo<intfi;
Foo<floatff;
ff.func(fi);

A common use is to write copy constructors this way to convert between
different template instantation of types.
Thank you for your explanation.
Now the problem is much clearer to me.

Best Regards
StephQ
May 17 '07 #5

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

Similar topics

1
3175
by: Gianni Mariani | last post by:
I have 2 distinct template classes which co-operate, hence are friends. However, I can't seem to figure out what syntax to use to make this work. What is the right(tm) way to write a friend class here ? Here is the code: template <typename A> class Y;
10
2199
by: william xuuu | last post by:
Actually, I also got linker errors with template functions and template classes. And I avoided both of them successfully, by pouring foo.cpp into foo.h, according to the C++ FAQ. (http://www.parashift.com/c++-faq-lite/containers-and-templates.html) And then, I pre-declared each template friend function above the definition of template class. But I still get template friends linker error. My compiler is gcc 3.3.3. Any hints? Thanks,
5
5641
by: Pete C. | last post by:
I'm trying to make a templated function a friend like this: class cls { ... friend cls func<> (const cls& a, const cls& b); }; template< template<class> class Op> cls func (const cls& a, const cls& b)
4
2684
by: BigMan | last post by:
This code does not compile on g++ 3.4.2. I want the template argument to be a friend of the template class. What syntax should I use to define such relationship? template< typename t > class t2 { friend t; // error: a class-key must be used when declaring a friend };
11
2589
by: Micha | last post by:
Hello there, I think I've run into some classic c++ pitfall and maybe some of you guys can help me out. For my project I will need to use matrices and vectors and so I decided to implement them by myself. I know there are already tons of vector and matrix implementations, but I wanted to have one taylored for my needs and without debugging someones else code. Also is's become somewhat personal meanwhile ;-).
7
2595
by: Noah Roberts | last post by:
template < typename V > class Outer { public: template < typename T > class Inner { private: template <classfriend class Inner; };
9
1693
by: Klaas Vantournhout | last post by:
Hi all, I have a question about friends functions of a template class. To make it simple, I would like to do something like this. Assume that I have a class foo with template T template<Tclass foo
2
5530
by: Dave Rudolf | last post by:
Hey all, So I have a template class whose only template parameter is a type that the class is to manage. It's actually an implementation of the common Singleton design pattern. The class looks like this: template< class Type > class Singleton
12
1736
by: siddhu | last post by:
Hello, would you suggest to me, why gcc 3.3.3 can not compile this: template<class T> class Base { Base(){} friend T; };
0
8826
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
8732
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
8503
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
7330
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...
1
6166
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
5632
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
4155
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
4306
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
2
1955
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.