473,320 Members | 2,071 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,320 software developers and data experts.

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<typename T>
class Foo {
friend void func (const Foo<T>& foo);
};

template<typename 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<typename T>
class Foo {

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

template<typename 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<typename T>
class Foo {

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

template<typename 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 1881
StephQ wrote:
According to:
http://www.parashift.com/c++-faq-lit....html#faq-35.4
, if my understanding is correct, in

template<typename T>
class Foo {
friend void func (const Foo<T>& foo);
};
You declared a non-template function func here...
>
template<typename 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<typename T>
class Foo {

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

template<typename 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<typename T>
class Foo {

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

template<typename 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<typename T>
class Foo {
public:
template<typename 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<Tdefinition 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<typename T>
class Foo {
public:
template<typename 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<typename 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...@aepnetworks.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<typename T>
class Foo {
public:
template<typename 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<Tdefinition 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<typename T>
class Foo {
public:
template<typename 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<typename 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
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...
10
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. ...
5
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,...
4
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...
11
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...
7
by: Noah Roberts | last post by:
template < typename V > class Outer { public: template < typename T > class Inner { private: template <classfriend class Inner; };
9
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 ...
2
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...
12
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
by: DolphinDB | last post by:
The formulas of 101 quantitative trading alphas used by WorldQuant were presented in the paper 101 Formulaic Alphas. However, some formulas are complex, leading to challenges in calculation. Take...
0
by: DolphinDB | last post by:
Tired of spending countless mintues downsampling your data? Look no further! In this article, you’ll learn how to efficiently downsample 6.48 billion high-frequency records to 61 million...
0
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
1
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
0
by: Vimpel783 | last post by:
Hello! Guys, I found this code on the Internet, but I need to modify it a little. It works well, the problem is this: Data is sent from only one cell, in this case B5, but it is necessary that data...
0
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
0
by: Defcon1945 | last post by:
I'm trying to learn Python using Pycharm but import shutil doesn't work
0
by: Shællîpôpï 09 | last post by:
If u are using a keypad phone, how do u turn on JavaScript, to access features like WhatsApp, Facebook, Instagram....
0
by: Faith0G | last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...

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.