471,071 Members | 1,516 Online
Bytes | Software Development & Data Engineering Community
Post +

Home Posts Topics Members FAQ

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

friend with template class

I have code like this

template<int size> big_int {
/* ... */
template<int size2> friend class big_int<size2>;
};

What I wanted to achive is to be able to easly convert different sized
big_int's and to operate on them. But for this I need to be able to access
private data of big_int. The problem is that for differenc sizes this are of
course different classes so I need friend declaration. But my compiler (MS
VS .NET 2005) does not accept this.
Is it possible? If no, how can I achive this except for declaring
private data public?

Thanks in advance.

Adam Badura
Apr 23 '06 #1
9 3463
"Adam Badura" <ab*****@o2.pl> wrote in message
news:e2**********@nemesis.news.tpi.pl
I have code like this

template<int size> big_int {
/* ... */
template<int size2> friend class big_int<size2>;
};

What I wanted to achive is to be able to easly convert different sized
big_int's and to operate on them. But for this I need to be able to
access private data of big_int. The problem is that for differenc
sizes this are of course different classes so I need friend
declaration. But my compiler (MS VS .NET 2005) does not accept this.
Is it possible? If no, how can I achive this except for declaring
private data public?

By using the correct syntax.

template<int size>
class big_int
{
/* ... */
template<int size2>
friend class big_int;
};
--
John Carson

Apr 23 '06 #2
> By using the correct syntax.

template<int size>
class big_int
{
/* ... */
template<int size2>
friend class big_int;
};


Hmmm....
Thanks. It worked. (As for my knowledge of C++ new lines after template
specifiers are not obligatory [and in my compiler {MS VS .NET 2005} it
worekd without them] - and this is just a style of writing code.)
Its funny, but I couldn't find any example in my books or on the Web
(but to be honset I didn't search very long). Perhabs it is not a popular
construct.
Thanks...

Adam Badura
Apr 23 '06 #3
"Adam Badura" <ab*****@o2.pl> wrote in message
news:e2**********@atlantis.news.tpi.pl
By using the correct syntax.

template<int size>
class big_int
{
/* ... */
template<int size2>
friend class big_int;
};


Hmmm....
Thanks. It worked. (As for my knowledge of C++ new lines after
template specifiers are not obligatory [and in my compiler {MS VS
.NET 2005} it worekd without them] - and this is just a style of
writing code.)


Indeed, the new lines are purely stylistic.

The corrections of substance are:

1. Adding the missing class identifier before the first big_int.

2. Deleting the <size2> after the second big_int.
--
John Carson
Apr 23 '06 #4
> 1. Adding the missing class identifier before the first big_int.

Ohh...
This was a simple mistake. I didn't paste this code from my projcet but
write it by hand and forgot about that...
2. Deleting the <size2> after the second big_int.


So as I supposed form your post. But why? I do not understend why is
this not specified? What if I wanted to be friend only to even sized
numbers? Something like this:

template<int size2> friend class big_int<size*2>;

now I cannot do this without specifing the specialization. And what is more
code like

friend class big_int<size*2>;

(for size begin template parametr in the class itself) works fine.

And besides it is strange to omit this <size2> if we specify for which
parameters this should be specialized. And even more, whatfor is
template<int size2> now?

Adam Badura
Apr 23 '06 #5
"Adam Badura" <ab*****@o2.pl> wrote in message
news:e2**********@atlantis.news.tpi.pl
1. Adding the missing class identifier before the first big_int.
Ohh...
This was a simple mistake. I didn't paste this code from my
projcet but write it by hand


Always a really bad idea.
2. Deleting the <size2> after the second big_int.
So as I supposed form your post. But why?


Because the C++ standard says so.
I do not understend why
is this not specified? What if I wanted to be friend only to even
sized numbers? Something like this:

template<int size2> friend class big_int<size*2>;

now I cannot do this without specifing the specialization.
This type of specialization is illegal at any time. It has nothing to do
with friendship. Try:

template<int size>
class Foo
{};

template<int size>
class Foo<size*2>
{};

This won't compile. You aren't allowed to form algebraic expressions out of
the template parameters when partially specializing.
And what is more code like

friend class big_int<size*2>;

(for size begin template parametr in the class itself) works fine.
Sure, that means that if you declare

big_int<5> bi;

then you are granting friendship to instances of big_int<10>. You are not
partially specializing.
And besides it is strange to omit this <size2> if we specify for
which parameters this should be specialized. And even more, whatfor is
template<int size2> now?


With

template<int size>
class big_int
{
/* ... */
template<int n>
friend class big_int;
};

when you declare

big_int<5> bi;

you make big_int<n> a friend for every int n. This is an "unbound friend"
declaration, i.e., the friend doesn't need to have the same parameter.

With

template<int size>
class big_int
{
/* ... */
friend class big_int;
};
when you declare

big_int<5> bi;

you only make big_int<5> a friend. This is a "bound friend" declaration,
i.e., the friend must have the same parameter value.

If you are going to make extensive use of templates, I recommend C++
Templates: The Complete Guide by David Vandevoorde and Nicolai Josuttis.

--
John Carson
Apr 24 '06 #6
> If you are going to make extensive use of templates, I recommend C++
Templates: The Complete Guide by David Vandevoorde and Nicolai Josuttis.


OK. Greate thanks...
To be honest I think I know C++ :), but this is something I have never
used (and as I have writen I couldn't find it in Stroustrup for example). So
now I will have to search for some info in this area with your replyes as a
quide. Thanks.

Adam Badura
Apr 24 '06 #7
Adam Badura wrote:
2. Deleting the <size2> after the second big_int.

So as I supposed form your post. But why? I do not understend why is
this not specified? What if I wanted to be friend only to even sized
numbers? Something like this:

template<int size2> friend class big_int<size*2>;


size*2 doesn't depend on size2. Is that really what you meant?

now I cannot do this without specifing the specialization. And what is more
code like

friend class big_int<size*2>;

(for size begin template parametr in the class itself) works fine.
Yes,
friend class big_int<size*2>;
is perfectly valid. The two cases are different - in one case you are
declaring friendship for all specializations of a template, in the other
case just a particular specialization. You'd expect the syntax to be
different, no?

One thing you can't do though is declare friendship for a partial
specialization, and there's no particularly good reason for that, it's
just the way it is. (e.g. this is illegal:
template<int size2> friend class big_int<size2*2>;
as an attempt to declare friendship only to even specializations).
And besides it is strange to omit this <size2> if we specify for which
parameters this should be specialized. And even more, whatfor is
template<int size2> now?


To show that every specialization is being granted friendship.

Tom
Apr 24 '06 #8
>> template<int size2> friend class big_int<size*2>;

size*2 doesn't depend on size2. Is that really what you meant?
No. Of course i meant

template<int size2> friend class big_int<size2*2>;
One thing you can't do though is declare friendship for a partial
specialization, and there's no particularly good reason for that, it's
just the way it is. (e.g. this is illegal:
template<int size2> friend class big_int<size2*2>;
as an attempt to declare friendship only to even specializations).
OK. And that is the thing I wanted to know. (Really I needed only this
what I got in first reply, but as the whole thing started I want to get as
much of it as I can :).) However it seems kind of strang that this is
illegal - but on the other hand this is not the only thing strange... :)
To show that every specialization is being granted friendship.


But why couldn't it be written like this

friend class big_int;

Is it because in this case this means by default big_int<size> (where size
is ta paramter name for the class) like for declaring functions?

Adam Badura
Apr 24 '06 #9
Adam Badura wrote:
To show that every specialization is being granted friendship.

But why couldn't it be written like this

friend class big_int;


Well, in the general case you don't know whether big_int is a template
or not, since it might not have been declared yet, so the syntax with
the template <...> bit makes it explicit whether it is a template or
just a plain class that is being granted friendship.

Where big_int is a the class itself, then you have the name-injection
problem you mentioned.

But syntax is just an arbitrary choice in many cases - the "why" is
often not very interesting.

Tom
Apr 24 '06 #10

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

4 posts views Thread by Bonzo | last post: by
2 posts views Thread by Christophe Barbe | last post: by
2 posts views Thread by Christophe Barbe | last post: by
1 post views Thread by Dmitry D | last post: by
5 posts views Thread by Trevor Lango | last post: by
6 posts views Thread by Adam Parkin | last post: by
5 posts views Thread by Ruben Campos | last post: by

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.