syntax: howto write partial template friend declaration

F

farseerfc

Hi, everyone here loves C++;
As a student studying data structure, I'm writting a single list (with only
one pointer to identity the next node in its node struct) simulating
std::list like:

template <typename T, typename Alloc> class slist {...};

Here Alloc accepts a std::allcator . And within the same namespace I wrote
its iterator:

template <typename T> class slist_iterator {...};

the problem is that when I want to say slist is slist_iterator's friend, I
can't find a syntax to express exactly what I want, I mean when I write in
side slist_iterator:

//inside slist_iterator
template <typename Ty,typename Alloc> friend class slist;

all kinds of slists is the friend of slist_iterator now, ie,
slist<double,std::allocator<double> > is also a friend of
slist_iterator<int> , that is not what I want.And I can not write this:

friend class slist<T,Alloc>;

because inside slist_iterator there is no information about Alloc.
What I want is a partial template friend declaration, something like a
partial template specialization:

template<typename Alloc> friend class slist<T,Alloc>;

that means all slist with the same element type is the friend of
slist_iterator, but no more further.
But in all compilers I tested, the sentence above is a syntax error.
So can I / howto write this , is there any syntax support or
metaprogramming tech to achieve this ?
 
T

Triple-DES

Hi, everyone here loves C++;
As a student studying data structure, I'm writting a single list (with only
one pointer to identity the next node in its node struct) simulating
std::list like:

template <typename T, typename Alloc> class slist {...};

Here Alloc accepts a std::allcator . And within the same namespace I wrote
its iterator:

template <typename T> class slist_iterator {...};

the problem is that when I want to say slist is slist_iterator's friend, I
can't find a syntax to express exactly what I want, I mean when I write in
side slist_iterator:

//inside slist_iterator
template <typename Ty,typename Alloc> friend class slist;

all kinds of slists is the friend of slist_iterator now, ie,
slist<double,std::allocator<double> > is also a friend of
slist_iterator<int> , that is not what I want.And I can not write this:

friend class slist<T,Alloc>;

because inside slist_iterator there is no information about Alloc.
What I want is a partial template friend declaration, something like a
partial template specialization:

template<typename Alloc> friend class slist<T,Alloc>;

that means all slist with the same element type is the friend of
slist_iterator, but no more further.
But in all compilers I tested, the sentence above is a syntax error.
So  can I / howto write this , is there any syntax support or
metaprogramming tech to achieve this ?

First of all, why do you need class slist to be a friend of
slist_iterator?
Are you sure you don't want it the other way around? (let the iterator
access the list's private members)

Because that would be pretty simple:
template<typename T, typename Alloc> class slist
{
friend class slist_iterator<T>;
// ...
};

DP
 
F

farseerfc

First of all, thank you;
I just simply want the list have access to the private member of the
iterator, many member functions of list(like merge,reverse,etc.) needs this
to change the order of the nodes with no creating/deleting nodes.

Maybe I can write iterator inside list to achieve this (maybe, I haven't
test yet.) And to be frank, this is a part of assignments of my data
structure course, and according to the requirement of the assignment, these
two classes should be apart from each other.

The most interesting thing is the thinking why C++ doesn't supply such kind
of syntax like "partial template friend declaration" . We have already got
template friend ... I try to image that there is some kind of
metaprogramming skill can achieve this goal so I asked it here

;-P

tkank you,and thank you all
 
T

Triple-DES

First of all, thank you;
I just simply want the list have access to the private member of the
iterator, many member functions of list(like merge,reverse,etc.) needs this
to change the order of the nodes with no creating/deleting nodes.

Maybe I can write iterator inside list to achieve this (maybe, I haven't
test yet.) And to be frank, this is a part of assignments of my data
structure course, and according to the requirement of the assignment, these
two classes should be apart from each other.

The most interesting thing is the thinking why C++ doesn't supply such kind
of syntax like "partial template friend declaration" . We have already got
template friend ... I try to image that there is some kind of
metaprogramming skill can achieve this goal so I asked it here

;-P

tkank you,and thank you all

In that case I would simply add the Alloc as a template argument to
the iterator. Remember that iterators of slists with different
allocators should be different types. With your current design, they
are not.

template<typename T, typename Alloc>
class slist_iterator
{
friend class slist<T, Alloc>
// ...
};
 
F

farseerfc

In this case, iterators of slists with different allocators are not the
same, but I still think the syntax should be useful in other cases.

Actually,in my design, there is another template parameter bool circle to
indicate whether this slist should be a circle single list( whether the
last_node->next should be NULL or slist's head):

template <typename T,bool circle, typename Alloc> class slist;

And the iterator of these two kinds of slist should be the same class
because merge a sequence of non-circle slist into a circle slist is
reasonary, and vise versa as long as the sequence doesn't contain the head
node( which is used as the mark of the end of the circle slist and does not
store value).That means I wants to write something like this in the
iterator:

template<bool b> friend class slist<T,b,Alloc>;

Still in this case I can add to friend declare to avoid "partial".
But I do believe this partial syntax should be useful in some certain cases.
 
T

Triple-DES

Sorry,I mean I can add two friend declarations to avoid "partial" But...

Yes, I agree it would be useful in some cases. Unfortunately, it is
not allowed by the current standard, and as far as I know it won't
change in C++0x.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,774
Messages
2,569,599
Members
45,162
Latest member
GertrudeMa
Top