Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > How to declare a friend function of a template class?

Reply
Thread Tools

How to declare a friend function of a template class?

 
 
Rui Maciel
Guest
Posts: n/a
 
      07-12-2010
I have a class which has a set of friend functions. Now I wish to convert that class to a template
class but I'm having trouble declaring the friend functions of that template class. Can anyone
help? Any tip is more than welcomed.


Thanks in advance,
Rui Maciel
 
Reply With Quote
 
 
 
 
Victor Bazarov
Guest
Posts: n/a
 
      07-12-2010
On 7/12/2010 4:08 PM, Rui Maciel wrote:
> I have a class which has a set of friend functions. Now I wish to convert that class to a template
> class but I'm having trouble declaring the friend functions of that template class. Can anyone
> help? Any tip is more than welcomed.


class Boo { // has all instance of 'Foo' as friends
template<class T> friend class Foo;
};

If that doesn't fit your needs, perhaps you need to be more specific
(and post some code this time).

V
--
I do not respond to top-posted replies, please don't ask
 
Reply With Quote
 
 
 
 
Francesco S. Carta
Guest
Posts: n/a
 
      07-12-2010
Rui Maciel <(E-Mail Removed)>, on 12/07/2010 21:08:03, wrote:

> I have a class which has a set of friend functions. Now I wish to convert that class to a template
> class but I'm having trouble declaring the friend functions of that template class. Can anyone
> help? Any tip is more than welcomed.


It's a bit tricky, but possible:

//-------
template<class T> class foo {
public:
foo(T t): t(t) {}
protected:
T t;
template<class U> friend void inspect_foo(foo<U> f);
};

template<class T> void inspect_foo(foo<T> f) {
cout << f.t << endl;
}
//-------


--
FSC - http://userscripts.org/scripts/show/59948
http://fscode.altervista.org - http://sardinias.com
 
Reply With Quote
 
Francesco S. Carta
Guest
Posts: n/a
 
      07-12-2010
Francesco S. Carta <(E-Mail Removed)>, on 12/07/2010 22:29:59, wrote:

> Rui Maciel <(E-Mail Removed)>, on 12/07/2010 21:08:03, wrote:
>
>> I have a class which has a set of friend functions. Now I wish to
>> convert that class to a template
>> class but I'm having trouble declaring the friend functions of that
>> template class. Can anyone
>> help? Any tip is more than welcomed.

>
> It's a bit tricky, but possible:
>
> //-------
> template<class T> class foo {
> public:
> foo(T t): t(t) {}
> protected:
> T t;
> template<class U> friend void inspect_foo(foo<U> f);
> };
>
> template<class T> void inspect_foo(foo<T> f) {
> cout << f.t << endl;
> }
> //-------
>


Well, no, the word I meant to use wasn't exactly "tricky" but more on
the side of "verbose / tedious" - if you have lots of overloads it's way
easier to put them in a class and make that a friend, just like
suggested by Victor.

I wonder what's the rationale of not allowing to simply say:

friend function_name;

and set all overloads of "function_name" as friends, regardless of their
arguments or return types - I suppose the mechanism is not as simple as
I'd expect it to be, with these words of mine.

--
FSC - http://userscripts.org/scripts/show/59948
http://fscode.altervista.org - http://sardinias.com
 
Reply With Quote
 
Paul Bibbings
Guest
Posts: n/a
 
      07-12-2010
"Francesco S. Carta" <(E-Mail Removed)> writes:

> Rui Maciel <(E-Mail Removed)>, on 12/07/2010 21:08:03, wrote:
>
>> I have a class which has a set of friend functions. Now I wish to
>> convert that class to a template class but I'm having trouble
>> declaring the friend functions of that template class. Can anyone
>> help? Any tip is more than welcomed.

>
> It's a bit tricky, but possible:
>
> //-------
> template<class T> class foo {
> public:
> foo(T t): t(t) {}
> protected:
> T t;
> template<class U> friend void inspect_foo(foo<U> f);
> };
>
> template<class T> void inspect_foo(foo<T> f) {
> cout << f.t << endl;
> }
> //-------


This is not an incorrect example, I do not think. However, note that
parameterization of inspect_foo as a friend of class foo makes *all*
specializations of inspect_foo a friend of any particular specialization
of class foo, which seems a little arbitrary. If, on the other hand, we
look at a similar example in which only inspect_foo<aType>(foo<aType>)
is a friend of foo<aType>, then the requirements of declaring a function
template a friend of a parameterized type begin to look a little less
straight forward, as I believe the following would be required:

#include <iostream>

using namespace std;

template<class T>
class foo; // forward declaration of foo

template<class T>
void inspect_foo(foo<T>); // foward declaration of friend

template<class T>
class foo { // definition of foo
public:
foo(T t): t(t) { }
protected:
T t;
friend void inspect_foo<>(foo<T> f);
};

template<class T>
void inspect_foo(foo<T> f) { // definition of friend function
cout << f.t << endl;
}

int main()
{
inspect_foo(foo<int>(1));
}

Regards

Paul Bibbings
 
Reply With Quote
 
Francesco S. Carta
Guest
Posts: n/a
 
      07-12-2010
Paul Bibbings <(E-Mail Removed)>, on 12/07/2010 22:25:09, wrote:

> "Francesco S. Carta"<(E-Mail Removed)> writes:
>
>> Rui Maciel<(E-Mail Removed)>, on 12/07/2010 21:08:03, wrote:
>>
>>> I have a class which has a set of friend functions. Now I wish to
>>> convert that class to a template class but I'm having trouble
>>> declaring the friend functions of that template class. Can anyone
>>> help? Any tip is more than welcomed.

>>
>> It's a bit tricky, but possible:
>>
>> //-------
>> template<class T> class foo {
>> public:
>> foo(T t): t(t) {}
>> protected:
>> T t;
>> template<class U> friend void inspect_foo(foo<U> f);
>> };
>>
>> template<class T> void inspect_foo(foo<T> f) {
>> cout<< f.t<< endl;
>> }
>> //-------

>
> This is not an incorrect example, I do not think. However, note that
> parameterization of inspect_foo as a friend of class foo makes *all*
> specializations of inspect_foo a friend of any particular specialization
> of class foo, which seems a little arbitrary.


I don't think that would be a problem: after all, there is no way to
pass a "wrong" foo to inspect_foo.

> If, on the other hand, we
> look at a similar example in which only inspect_foo<aType>(foo<aType>)
> is a friend of foo<aType>, then the requirements of declaring a function
> template a friend of a parameterized type begin to look a little less
> straight forward, as I believe the following would be required:
>
> #include<iostream>
>
> using namespace std;
>
> template<class T>
> class foo; // forward declaration of foo
>
> template<class T>
> void inspect_foo(foo<T>); // foward declaration of friend
>
> template<class T>
> class foo { // definition of foo
> public:
> foo(T t): t(t) { }
> protected:
> T t;
> friend void inspect_foo<>(foo<T> f);
> };
>
> template<class T>
> void inspect_foo(foo<T> f) { // definition of friend function
> cout<< f.t<< endl;
> }
>
> int main()
> {
> inspect_foo(foo<int>(1));
> }


As a further proof that C++ can really become tedious and verbose, at times.

Luckily, we can declare friend classes and fly straight over all this
awful machinery

--
FSC - http://userscripts.org/scripts/show/59948
http://fscode.altervista.org - http://sardinias.com
 
Reply With Quote
 
Rui Maciel
Guest
Posts: n/a
 
      07-12-2010
Victor Bazarov wrote:

> class Boo { // has all instance of 'Foo' as friends
> template<class T> friend class Foo;
> };
>
> If that doesn't fit your needs, perhaps you need to be more specific
> (and post some code this time).


Thanks for the help, Victor. Nonetheless, instead of a friend class I was looking for a way to
declare friend functions of a template class, like Francesco did.


Thanks anyway,
Rui Maciel



 
Reply With Quote
 
Rui Maciel
Guest
Posts: n/a
 
      07-12-2010
Francesco S. Carta wrote:

> It's a bit tricky, but possible:
>
> //-------
> template<class T> class foo {
> public:
> foo(T t): t(t) {}
> protected:
> T t;
> template<class U> friend void inspect_foo(foo<U> f);
> };
>
> template<class T> void inspect_foo(foo<T> f) {
> cout << f.t << endl;
> }
> //-------


I've followed your suggestion and it appears that it works. I thought that the declaration of a
template friend function would be something like:

<code>

template<class T> class foo {
public:
foo(T t): t(t) {}
protected:
T t;
template<class T> friend void inspect_foo(foo<T> f);
};

template<class T> void inspect_foo(foo<T> f) {
cout << f.t << endl;
}

</code>

Is there a reason for that not to work?


Rui Maciel
 
Reply With Quote
 
Francesco S. Carta
Guest
Posts: n/a
 
      07-13-2010
Rui Maciel <(E-Mail Removed)>, on 12/07/2010 23:41:05, wrote:

> Francesco S. Carta wrote:
>
>> It's a bit tricky, but possible:
>>
>> //-------
>> template<class T> class foo {
>> public:
>> foo(T t): t(t) {}
>> protected:
>> T t;
>> template<class U> friend void inspect_foo(foo<U> f);
>> };
>>
>> template<class T> void inspect_foo(foo<T> f) {
>> cout<< f.t<< endl;
>> }
>> //-------

>
> I've followed your suggestion and it appears that it works. I thought that the declaration of a
> template friend function would be something like:
>
> <code>
>
> template<class T> class foo {
> public:
> foo(T t): t(t) {}
> protected:
> T t;
> template<class T> friend void inspect_foo(foo<T> f);
> };
>
> template<class T> void inspect_foo(foo<T> f) {
> cout<< f.t<< endl;
> }
>
> </code>
>
> Is there a reason for that not to work?


The above is reported as "shadowing" by my compiler, and, at the same
time, it tells that it happens to be an error.

I don't really know the rationale behind making such "shadowing" an
error instead of (just) a warning.

By the way, just for fiddling, I've made this test which sort of take
advantage of NOT shadowing T (well, OK, I am not allowed to shadow it in
any case, so no big "taking"):

//-------
#include <iostream>

using namespace std;

template<class T> class foo {
public:
foo(T t): t(t) {}
T get_t() {
return t;
}
private:
T t;
template<class U> friend void inspect(foo<U> f, T t);
};

template<class W> void inspect(foo<W> f, int i) {
// accesses the private interface
cout << f.t << endl;
cout << i << endl;
}

template<class W> void inspect(foo<W> f, double d) {
// accesses the private interface
cout << f.t << endl;
cout << d << endl;
}

template<class W> void inspect(foo<W> f, const char* cstr) {
// accesses only the public interface
cout << f.get_t() << endl;
cout << cstr << endl;
}

int main() {
foo<int> i(42);
foo<double> d(4.2);

// (int, int) compiles as a friend
inspect(i, 7;

// (double, double) compiles as a friend
inspect(d, 7.;

// (not an int, int) error: not a friend!
//inspect(d, 7;

// (not a double, double) error: not a friend!
//inspect(i, 7.;

// (whatever, const char*) compiles - not a friend, no need to
inspect(i, "int");
inspect(d, "double");

return 0;
}
//-------


In the above code only the "inspect" instantiations whose second
parameter's type matches the (inspect's) template type are allowed to
access the "innards" of "foo" (whatever its type), all the others can
only access its public interface.

I'm not able to see any immediate use of this - although I think someone
must have used something like this, somewhere.

The point could be: to do the above I've "had" to use the name "T" in
the declaration of "inspect", within of "foo".

Had I used "T" as "inspect" template parameter (shadowing "foo"'s
template parameter) that trick would have been impossible.

And with "trick" I mean "declaring, with a single line, a friend
function that is a /true friend/ only when its parameters equate each other"

Still, that's not enough of a reason to forbid shadowing.

I'm not so sure I could be able to understand all that I wrote here above.

That could be my English' fault. That could be the late hour's fault.
That could well be the templates' fault - or my understanding of them,
more likely

Templates: lovely, tricky bastards. Good night.

--
FSC - http://userscripts.org/scripts/show/59948
http://fscode.altervista.org - http://sardinias.com
 
Reply With Quote
 
Vladimir Jovic
Guest
Posts: n/a
 
      07-13-2010
Rui Maciel wrote:
> Francesco S. Carta wrote:
>
>> It's a bit tricky, but possible:
>>
>> //-------
>> template<class T> class foo {
>> public:
>> foo(T t): t(t) {}
>> protected:
>> T t;
>> template<class U> friend void inspect_foo(foo<U> f);
>> };
>>
>> template<class T> void inspect_foo(foo<T> f) {
>> cout << f.t << endl;
>> }
>> //-------

>
> I've followed your suggestion and it appears that it works. I thought that the declaration of a
> template friend function would be something like:
>
> <code>
>
> template<class T> class foo {
> public:
> foo(T t): t(t) {}
> protected:
> T t;
> template<class T> friend void inspect_foo(foo<T> f);
> };
>
> template<class T> void inspect_foo(foo<T> f) {
> cout << f.t << endl;
> }
>
> </code>
>
> Is there a reason for that not to work?


1) you are missing main() and includes
2) When you fix 1, then you should get a compiler complaining about
shadowing a template parameter. The problem is, you are declaring two
class types with the same name T, and that is not allowed. How would the
compiler differentiate two?

Maybe you wanted something like this :


#include <iostream>
using namespace std;
template<class T> class foo {
public:
foo(T t): t(t) {}
protected:
T t;
inline friend void inspect_foo( const foo< T > &f )
{
cout << f.t << endl;
}
};

int main()
{
foo< int > a(5);
inspect_foo(a);
}

But see what Paul Bibbings wrote in other tread.
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Re: How include a large array? Edward A. Falk C Programming 1 04-04-2013 08:07 PM
how to declare friend for template class ? slocum C++ 4 04-10-2008 04:47 AM
Declare a Friend function which is a template member function of adifferent class getrakesh@gmail.com C++ 2 02-26-2008 11:32 AM
How can I declare and define a friend template function in a template class? =?gb2312?B?wfXquw==?= C++ 10 08-01-2007 01:48 AM
forward declare member function so that it can be friend function yancheng.cheok@gmail.com C++ 1 11-09-2006 11:30 AM



Advertisments