On 2008-02-17 16:46:39 -0500, Jeff Schwab
> Kira Yamato wrote:
>> A question about declaring a friend class. The following does not compile:
>>
>> template
>> class B
>> {
>> public:
>>
>> friend class C;
>> };
>>
>> g++4.0.1 returns the error message
>>
>> error: using template type parameter 'C' after 'class'
>>
>>
>> So, is there a way to declare a friend class from the template parameter?
>
> NB: I'm not sure why you want to do this, and I don't necessarily endorse it.
>
> AFAIK, you would have to specialize the template explicitly for each
> parameter type. For example:
>
> template
>
> struct S { };
>
> template<> struct B { friend class S; };
>
> You could write a macro to create specializations:
>
> template
>
> #define SPECIALIZE_B(param) \
> template<> struct B { friend class param; }
>
> struct S { };
> struct T { };
>
> SPECIALIZE_B(S);
> SPECIALIZE_B(T);
>
> Btw, why do you actually want this feature?
Well, I'm trying to write a template to implement some inner classes.
To be more specific, I have the following template
template
class member_accessor : private noncopyable
{
public:
member_accessor(C &c) : c(c) {}
operator M() const { return (c.*get)(); }
member_accessor &operator=(const M &n) { (c.*set)(n); return *this; }
private:
C &c;
};
This template allows me to write the following:
class A
{
public:
A() : x(*this) {}
int get_x() const;
void set_x(const int &y);
member_accessor x;
};
A a;
a.x = 3; // actually invokes a.set_x(3);
int y = a.x; // actually invokes y = a.get_x();
However, I want to hide the constructor of 'member_accessor' so that
only the container class C can initiate object of type
member_accessor
The way I thought of doing that is to move the constructor to private
in the member_accessor template and declare the template parameter
class C as friend. That is,
template
class member_accessor : private noncopyable
{
public:
operator M() const { return (c.*get)(); }
member_accessor &operator=(const M &n) { (c.*set)(n); return *this; }
private:
member_accessor(C &c) : c(c) {} // constructor moved to private.
C &c;
friend class C; // (*) declare class C friend so that C can access
the private constructor.
};
But the g++4.0.1 won't allow line (*).
--
// kira