Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

CRTP, member typedefs and access control

3 views
Skip to first unread message

Hicham Mouline

unread,
Mar 26, 2009, 12:37:20 PM3/26/09
to
Hello,

I have the following situation:


template<typename Concrete>
class Base {

private:
typedef typename Concrete::Type1 t;

// use type t
};

class Derived : private Base<Derived> {
private:
typedef double Type1;
};


Can this work? I get fairly complicated error messages with which I'm having
a hard time deciphering,
and I'm not sure Type1 is the cause.
Do I need to declare friendship?

regards,


Victor Bazarov

unread,
Mar 26, 2009, 1:35:25 PM3/26/09
to

Certainly. The template is not allowed to see the privates of the type
for which it's instantiated, unless it's a friend.

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask

Lionel B

unread,
Mar 26, 2009, 1:40:51 PM3/26/09
to
On Thu, 26 Mar 2009 16:37:20 +0000, Hicham Mouline wrote:

> Hello,
>
> I have the following situation:
>
> template<typename Concrete>
> class Base {
>
> private:
> typedef typename Concrete::Type1 t;
>
> // use type t
> };
>
> class Derived : private Base<Derived> { private:
> typedef double Type1;
> };
>
>
> Can this work?

Can what work? What are you trying to achieve?

This just looks weird to me... class Derived derives from a templated
base instantiated with *class Derived itself* as template parameter ?!?
Why? What can you do with this? Am I missing something?

--
Lionel B

Hicham Mouline

unread,
Mar 26, 2009, 1:52:09 PM3/26/09
to
"Victor Bazarov" <v.Aba...@comAcast.net> wrote in message
news:gqgect$nh3$2...@news.datemas.de...

> Hicham Mouline wrote:
>> I have the following situation:
>>
>>
>> template<typename Concrete>
>> class Base {
>>
>> private:
>> typedef typename Concrete::Type1 t;
>>
>> // use type t
>> };
>>
>> class Derived : private Base<Derived> {
>> private:
>> typedef double Type1;
>> };
>>
>>
>> Can this work? I get fairly complicated error messages with which I'm
>> having a hard time deciphering,
>> and I'm not sure Type1 is the cause.
>> Do I need to declare friendship?
>
> Certainly. The template is not allowed to see the privates of the type
> for which it's instantiated, unless it's a friend.
>
> V
----
So declaring a
friend class Base<Derived >;

I thought this meant that all member functions of Base<Derived > were
friends of Derived.
that it didn't affect the reachabilily of private types of Derived in
Base<Derived > at class scope?

regards,


Victor Bazarov

unread,
Mar 26, 2009, 2:02:20 PM3/26/09
to
Hicham Mouline wrote:
> "Victor Bazarov" <v.Aba...@comAcast.net> wrote in message
> news:gqgect$nh3$2...@news.datemas.de...
>> Hicham Mouline wrote:
>>> I have the following situation:
>>>
>>>
>>> template<typename Concrete>
>>> class Base {
>>>
>>> private:
>>> typedef typename Concrete::Type1 t;
>>>
>>> // use type t
>>> };
>>>
>>> class Derived : private Base<Derived> {
>>> private:
>>> typedef double Type1;
>>> };
>>>
>>>
>>> Can this work? I get fairly complicated error messages with which I'm
>>> having a hard time deciphering,
>>> and I'm not sure Type1 is the cause.
>>> Do I need to declare friendship?
>> Certainly. The template is not allowed to see the privates of the type
>> for which it's instantiated, unless it's a friend.
>>
>> V
> ----
> So declaring a
> friend class Base<Derived >;

I sincerely hope you've put this declaration in the 'Derived' class.

> I thought this meant that all member functions of Base<Derived > were
> friends of Derived.

Yes, they are by inclusion. Scope of the member function is essentially
the scope of the class, so the accessibility rules spread throughout the
entire 'Base<Derived>' class and extend into member functions.

> that it didn't affect the reachabilily of private types of Derived in
> Base<Derived > at class scope?

I don't think I understand that sentence, sorry...

Victor Bazarov

unread,
Mar 26, 2009, 2:03:06 PM3/26/09
to

Read up on "CRTP" (it stands for "curiously recursive template pattern").

Bart van Ingen Schenau

unread,
Mar 27, 2009, 4:09:58 AM3/27/09
to

No, this can not work, and declaring friendship will not help either.

The problem is that in the definition of Base<>, you can not refer to
members of a derived class, because at the point where Base<Derived>
gets instantiated, Derived is not defined yet.
See also this thread:
http://groups.google.com/group/comp.lang.c++/browse_frm/thread/562d5a77cf4c1f12/ed886cdc72de4649

Bart v Ingen Schenau

Lionel B

unread,
Mar 27, 2009, 5:26:41 AM3/27/09
to
On Thu, 26 Mar 2009 14:03:06 -0400, Victor Bazarov wrote:

> Lionel B wrote:
>> On Thu, 26 Mar 2009 16:37:20 +0000, Hicham Mouline wrote:
>>
>>> Hello,
>>>
>>> I have the following situation:
>>>
>>> template<typename Concrete>
>>> class Base {
>>>
>>> private:
>>> typedef typename Concrete::Type1 t;
>>>
>>> // use type t
>>> };
>>>
>>> class Derived : private Base<Derived> { private:
>>> typedef double Type1;
>>> };
>>>
>>>
>>> Can this work?
>>
>> Can what work? What are you trying to achieve?
>>
>> This just looks weird to me... class Derived derives from a templated
>> base instantiated with *class Derived itself* as template parameter ?!?
>> Why? What can you do with this? Am I missing something?
>
> Read up on "CRTP" (it stands for "curiously recursive template
> pattern").

Cheers, have done. So, not weird... curious.

My thought on seeing the code was that this couldn't be useful since it
would not be possible to reference the derived class in the base
definition, since the derived class would at that point be incomplete (as
another poster suggests is in fact the case for the OP's code).

--
Lionel B

Hicham Mouline

unread,
Mar 27, 2009, 5:53:59 AM3/27/09
to

"Bart van Ingen Schenau" <Bart.van.In...@ict.nl> wrote in message
news:dbfd1c58-b42b-4349...@z1g2000yqn.googlegroups.com...

>Bart v Ingen Schenau

Hi, after all,
I didn't need to derive the class from the base and have the CRTP. I moved
to containement,
where Based< Traits<Derived> > is now a private member of Derived.

Traits<Derived> contains whatever Base required to do its job,

rds,


0 new messages