By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
435,192 Members | 1,253 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 435,192 IT Pros & Developers. It's quick & easy.

friend with template class

P: n/a
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
Share this Question
Share on Google+
9 Replies


P: n/a
"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

P: n/a
> 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

P: n/a
"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

P: n/a
> 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

P: n/a
"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

P: n/a
> 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

P: n/a
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

P: n/a
>> 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

P: n/a
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.