Re: How to declare all forms of "more specialized" class template as friend?
On 6/13/07 1:29 PM, in article
1181760196.749206.177780@g37g2000prf.googlegroups.com, "yonil"
<silvatar_flood@yahoo.com> wrote:
Suppose I have a class template Foo which privately inherits a class
Bar:
template <class A, class B>
class Foo :
// user shouldn't ever gain access to Bar
private Bar
{
};
Suppose now that Foo is part of the implementation of another
template, Baz,
that depends on additional template arguments.
template <class X, class A, class Y, class B, class Z>
class Baz
{
// users should declare Foo's only as Baz<...>::my_foo_type
typedef Foo<A, B> my_foo_type;
// stuff
my_foo_type pikaboo()
{
my_foo_type result;
...
Bar& result_bar_ref = result; // doesn't work!! Bar is private
return result;
}
};
What I need to do for this to work is to have all possible classes of
the form Baz<X, A, Y, B, Z> (for any X, Y, Z) be a friend of class
Baz<A, B>.
Is there any way to achieve that?
No, not with the requirements as stated. A class may declare a class
template or as a class template specialization as its friend, but it may not
declare a class template partial specialization as a friend - which is
essentially what would be required here.
So about the only solutions that I can see would be to declare every Baz
specialization a friend of Foo's. And I don't see much reason not to do so:
after all, if Baz is a friend to some Foo specializations, there's not much
lost in Baz being a friend to all of them.
Alternately, it would be possible to define a "FooFriend" class template
that would be instantiated with just the two parameter types, A and B, from
Raz's type parameter list. Raz then would be declared a subclass of
FooFriend<A, B>. Raz's additional type parameters (X, Y, and Z) would then
be used to instantiated FooFriend's pikaboo() - which would be declared a
member template:
template <class T1, class T2> class FooFriend;
class Bar {};
template <class A, class B>
class Foo :
// user shouldn't ever gain access to Bar
private Bar
{
template< class T1, class T2> friend class FooFriend;
};
template <class T1, class T2>
class FooFriend
{
public:
typedef Foo<T1, T2> my_foo_type;
// pass policy types here
template <class T3, class T4, class T5>
my_foo_type pikaboo()
{
my_foo_type result;
// do some work here depending on template types and policies:
// T3, T4, T5
// we need access to the Bar object underlying the Foo type here
// in order to produce the result
Bar& result_bar_ref = result; // OK
return result;
}
};
template <class X, class A, class Y, class B, class Z>
class Baz : public FooFriend<A, B>
{
// users should declare Foo's only as Baz<...>::my_foo_type
public:
typedef typename FooFriend<A, B>::my_foo_type my_foo_type;
my_foo_type pikaboo()
{
// Note tricky syntax
return this->FooFriend<A, B>::template pikaboo<X, Y, Z>();
}
};
Greg
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]