CRTP

Discussion in 'C++' started by Noah Roberts, Jan 12, 2007.

  1. Noah Roberts

    Noah Roberts Guest

    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.
    Noah Roberts, Jan 12, 2007
    #1
    1. Advertising

  2. Noah Roberts

    Simon G Best Guest

    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?
    Simon G Best, Jan 12, 2007
    #2
    1. Advertising

  3. Noah Roberts

    Noah Roberts Guest

    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++.
    Noah Roberts, Jan 13, 2007
    #3
  4. Noah Roberts

    kwikius Guest

    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
    kwikius, Jan 13, 2007
    #4
  5. Noah Roberts

    Simon G Best Guest

    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, Jan 13, 2007
    #5
  6. Noah Roberts

    Simon G Best Guest

    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?
    Simon G Best, Jan 14, 2007
    #6
  7. Noah Roberts

    kwikius Guest

    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
    kwikius, Jan 15, 2007
    #7
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Mike Smith

    ABC vs. CRTP?

    Mike Smith, Mar 2, 2005, in forum: C++
    Replies:
    7
    Views:
    896
    Dietmar Kuehl
    Mar 3, 2005
  2. fabioppp

    CRTP question

    fabioppp, Apr 15, 2005, in forum: C++
    Replies:
    2
    Views:
    373
    James Aguilar
    Apr 15, 2005
  3. CRTP question

    , Apr 17, 2006, in forum: C++
    Replies:
    2
    Views:
    385
  4. CRTP and Factories

    , Jul 25, 2006, in forum: C++
    Replies:
    2
    Views:
    323
  5. Arash Partow

    Heterogeneous containers with CRTP

    Arash Partow, May 15, 2007, in forum: C++
    Replies:
    2
    Views:
    751
    Axter
    May 15, 2007
Loading...

Share This Page