CRTP, member typedefs and access control

H

Hicham Mouline

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,
 
V

Victor Bazarov

Hicham said:
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
 
L

Lionel B

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?
 
H

Hicham Mouline

Victor Bazarov said:
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,
 
V

Victor Bazarov

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 said:
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...

V
 
V

Victor Bazarov

Lionel said:
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").

V
 
B

Bart van Ingen Schenau

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?

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
 
L

Lionel B

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).
 
H

Hicham Mouline

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?
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

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,
 

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

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top