Velocity Reviews

Velocity Reviews (http://www.velocityreviews.com/forums/index.php)
-   C++ (http://www.velocityreviews.com/forums/f39-c.html)
-   -   CRTP (http://www.velocityreviews.com/forums/t459798-crtp.html)

Noah Roberts 01-12-2007 10:44 PM

CRTP
 
This isn't possible?

template < typename SUB >
struct Base
{
typedef typename SUB::dim dimen;
};

struct Sub : Base<Sub>
{
typedef int dim;
};

I was pretty sure it could be done.


Simon G Best 01-12-2007 11:42 PM

Re: CRTP
 
Noah Roberts wrote:
> This isn't possible?
>
> template < typename SUB >
> struct Base
> {
> typedef typename SUB::dim dimen;
> };
>
> struct Sub : Base<Sub>
> {
> typedef int dim;
> };
>
> I was pretty sure it could be done.


So was I. I can almost see, in my mind, the page where Stroustrup gives
an example of it in The C++ Programming Language, Third Edition. Well,
apart from the typedef in the class template, anyway.

I did try a variation:-

[Start C++ snippet.]

template<typename SUB, typename DIM = SUB::dim> struct Base {
typedef DIM dimen;
};

[End C++ snippet.]

but that didn't work, either. It's not hard to imagine why, as, when
that default parameter argument is used explicitly, you have:-

[Start C++ snippet.]

struct Sub : Base<Sub, Sub::dim> {
typedef int dim;
};

[End C++ snippet.]

which obviously won't work. Maybe there's a connection?

But yours really ought to work, oughtn't it? Or is it because the
compiler's trying to establish what the base part of Sub is, in detail,
in the course of establishing what Sub is, but finding that to do that,
it's got to establish what Sub is, in enough detail, in order to
establish what the base part of it is? I suspect that that might be it
- but it's only a suspicion.

--
Simon G Best
What happens if I mention Leader Kibo in my .signature?

Noah Roberts 01-13-2007 12:02 AM

Re: CRTP
 

Simon G Best wrote:
> Noah Roberts wrote:
> > This isn't possible?
> >
> > template < typename SUB >
> > struct Base
> > {
> > typedef typename SUB::dim dimen;
> > };
> >
> > struct Sub : Base<Sub>
> > {
> > typedef int dim;
> > };
> >
> > I was pretty sure it could be done.

>
> So was I. I can almost see, in my mind, the page where Stroustrup gives
> an example of it in The C++ Programming Language, Third Edition. Well,
> apart from the typedef in the class template, anyway.
>
> I did try a variation:-
>
> [Start C++ snippet.]
>
> template<typename SUB, typename DIM = SUB::dim> struct Base {
> typedef DIM dimen;
> };
>
> [End C++ snippet.]
>
> but that didn't work, either. It's not hard to imagine why, as, when
> that default parameter argument is used explicitly, you have:-
>
> [Start C++ snippet.]
>
> struct Sub : Base<Sub, Sub::dim> {
> typedef int dim;
> };
>
> [End C++ snippet.]
>
> which obviously won't work. Maybe there's a connection?
>
> But yours really ought to work, oughtn't it? Or is it because the
> compiler's trying to establish what the base part of Sub is, in detail,
> in the course of establishing what Sub is, but finding that to do that,
> it's got to establish what Sub is, in enough detail, in order to
> establish what the base part of it is? I suspect that that might be it
> - but it's only a suspicion.


It has to be some sort of scope thing. This works fine:


template < typename SUB >
struct Base
{
void f()
{
typedef typename SUB::dim dim;
}
};



But as soon as I try to access the type SUB::dim inside of the main
class structure it breaks down in both VC++ and g++.


kwikius 01-13-2007 11:57 AM

Re: CRTP
 
Noah Roberts wrote:
> This isn't possible?
>
> template < typename SUB >
> struct Base
> {
> typedef typename SUB::dim dimen;
> };
>
> struct Sub : Base<Sub>
> {
> typedef int dim;
> };
>
> I was pretty sure it could be done.


Base<Sub> must be completely known first in order to define Sub.
However when compiler tries to this it cannot find resolution for the
Sub::dim typedef, which it hasnt seen yet.

OTOH:

template <typename T>
struct dim;

template < typename SUB >
struct Base {
typedef typename dim<SUB>::type dimen;

};

struct Sub;

template <>
struct dim<Sub>{
typedef int type;
};

// In this version all required info is known
// before instantiation of Base<Sub> ...


struct Sub : Base<Sub> {};

regards
Andy Little


Simon G Best 01-13-2007 04:38 PM

Re: CRTP
 
kwikius wrote:
>
> Base<Sub> must be completely known first in order to define Sub.
> However when compiler tries to this it cannot find resolution for the
> Sub::dim typedef, which it hasnt seen yet.


A bit like trying to do the following:-

[Start C++ snippet.]

struct Sub;

struct Base {
typedef Sub::dim dimen; // Error.
};

struct Sub {
typedef int dim;
};

[End C++ snippet.]

Or:-

[Start C++ snippet.]

struct Base;

struct Sub
: Base // Error.
{
typedef int dim;
};

struct Base {
typedef Sub::dim dimen;
};

[End C++ snippet.]

--
Simon G Best
What happens if I mention Leader Kibo in my .signature?

Simon G Best 01-14-2007 10:46 PM

Re: CRTP
 
Noah Roberts wrote:
>
> It has to be some sort of scope thing. This works fine:
>
>
> template < typename SUB >
> struct Base
> {
> void f()
> {
> typedef typename SUB::dim dim;
> }
> };
>
>
>
> But as soon as I try to access the type SUB::dim inside of the main
> class structure it breaks down in both VC++ and g++.


I bet this would work, too:-

struct Base {
void f();
};

struct Sub : public Base {
typedef int dim;
};

void Base::f() {
typedef Sub::dim dim;
}

But trying to have the typedef in struct Base directly would obviously
not be possible, because we'd need to define both structs before each
other. It seems the template case is the same (except you can define
Base<>::foo() within the struct definition).

:-)

--
Simon G Best
What happens if I mention Leader Kibo in my .signature?

kwikius 01-15-2007 09:39 AM

Re: CRTP
 

Simon G Best wrote:
> Noah Roberts wrote:
> >
> > It has to be some sort of scope thing. This works fine:
> >
> >
> > template < typename SUB >
> > struct Base
> > {
> > void f()
> > {
> > typedef typename SUB::dim dim;
> > }
> > };
> >
> >
> >
> > But as soon as I try to access the type SUB::dim inside of the main
> > class structure it breaks down in both VC++ and g++.

>
> I bet this would work, too:-
>
> struct Base {
> void f();
> };
>
> struct Sub : public Base {
> typedef int dim;
> };
>
> void Base::f() {
> typedef Sub::dim dim;
> }


In fact the following will also work because f is only instantiated
when reqd:


#include <iostream>

template <typename SUB>
struct Base {
void f(){
typedef typename SUB::dim dim;
std::cout << "something : " << dim() <<'\n';
}
};


struct Sub : public Base<Sub>{
typedef int dim;
};

int main()
{
Sub ss;
ss.f();
}

regards
Andy Little



All times are GMT. The time now is 10:10 PM.

Powered by vBulletin®. Copyright ©2000 - 2014, vBulletin Solutions, Inc.
SEO by vBSEO ©2010, Crawlability, Inc.