MoreCRTP question

Discussion in 'C++' started by kostas, Apr 20, 2007.

  1. kostas

    kostas Guest

    Hi all
    I encountered a problem testing a variation of CRTP.
    (It's also proposed in "C++ Templates: The Complete Guide" by
    Vandevoorde, Josuttis. See the MoreCurious template class in 16.3)

    template<class T, template <typename> class D>
    class Base
    {
    protected:
    Base(T x): i(x) {}

    T i;
    };

    template<class T>
    class Derived:public Base<T, Derived>
    {
    Derived(T x):Base<T, Derived>(x){}
    };

    the problem is that in the Base ctor call (from within Derived ctor)
    the Derived parameter is not recognized as class template. Old gcc
    versions(3.3.3) could cope with this, but not any more. Other
    compilers have also problem.

    So is it a language or a compiler issue?
    Do you know some workaround?
    Any help is appreciated.

    Kostas
     
    kostas, Apr 20, 2007
    #1
    1. Advertising

  2. kostas

    Ian Collins Guest

    kostas wrote:
    > Hi all
    > I encountered a problem testing a variation of CRTP.
    > (It's also proposed in "C++ Templates: The Complete Guide" by
    > Vandevoorde, Josuttis. See the MoreCurious template class in 16.3)
    >
    > template<class T, template <typename> class D>
    > class Base
    > {
    > protected:
    > Base(T x): i(x) {}
    >
    > T i;
    > };
    >
    > template<class T>
    > class Derived:public Base<T, Derived>
    > {
    > Derived(T x):Base<T, Derived>(x){}
    > };
    >
    > the problem is that in the Base ctor call (from within Derived ctor)
    > the Derived parameter is not recognized as class template. Old gcc
    > versions(3.3.3) could cope with this, but not any more. Other
    > compilers have also problem.
    >
    > So is it a language or a compiler issue?


    It looks OK to me and Sun CC accepts it.

    --
    Ian Collins.
     
    Ian Collins, Apr 20, 2007
    #2
    1. Advertising

  3. * kostas:
    > Hi all
    > I encountered a problem testing a variation of CRTP.
    > (It's also proposed in "C++ Templates: The Complete Guide" by
    > Vandevoorde, Josuttis. See the MoreCurious template class in 16.3)
    >
    > template<class T, template <typename> class D>
    > class Base
    > {
    > protected:
    > Base(T x): i(x) {}
    >
    > T i;
    > };
    >
    > template<class T>
    > class Derived:public Base<T, Derived>
    > {
    > Derived(T x):Base<T, Derived>(x){}
    > };
    >
    > the problem is that in the Base ctor call (from within Derived ctor)
    > the Derived parameter is not recognized as class template. Old gcc
    > versions(3.3.3) could cope with this, but not any more. Other
    > compilers have also problem.
    >
    > So is it a language or a compiler issue?
    > Do you know some workaround?
    > Any help is appreciated.


    I failed to find anything about it in the standard, but adding the magic
    word "class" before "Derived" seems to do the trick.

    --
    A: Because it messes up the order in which people normally read text.
    Q: Why is it such a bad thing?
    A: Top-posting.
    Q: What is the most annoying thing on usenet and in e-mail?
     
    Alf P. Steinbach, Apr 20, 2007
    #3
  4. kostas

    kostas Guest

    On Apr 20, 12:47 pm, "Alf P. Steinbach" <> wrote:
    > I failed to find anything about it in the standard, but adding the magic
    > word "class" before "Derived" seems to do the trick.


    if you mean this:
    template<class T>
    class Derived:public Base<T, Derived>
    {
    public:
    Derived(T x):Base<T, class Derived>(x){}

    };

    it doesn't work for me(gcc 3.4.4 or 4.1.1)
    what compiler do you use?
     
    kostas, Apr 20, 2007
    #4
  5. * kostas:
    > On Apr 20, 12:47 pm, "Alf P. Steinbach" <> wrote:
    >> I failed to find anything about it in the standard, but adding the magic
    >> word "class" before "Derived" seems to do the trick.

    >
    > if you mean this:
    > template<class T>
    > class Derived:public Base<T, Derived>
    > {
    > public:
    > Derived(T x):Base<T, class Derived>(x){}
    >
    > };
    >
    > it doesn't work for me(gcc 3.4.4 or 4.1.1)
    > what compiler do you use?


    MSVC 7.1, but now that I checked it with Comeau Online it's evidently an
    MS extension, not kosher, so no wonder I didn't find it in the standard.

    I don't see any solution to the technical problem, how to refer to
    Derived as a general non-specialized template within the Derived class.

    However, it shouldn't be difficult to create a workaround at the design
    level. E.g., simply move whatever functionality that Base uses in
    Derived, to some other class, e.g. another base class of Derived. Or
    perhaps you don't really need a template template parameter, perhaps all
    that's needed is an ordinary type parameter.

    --
    A: Because it messes up the order in which people normally read text.
    Q: Why is it such a bad thing?
    A: Top-posting.
    Q: What is the most annoying thing on usenet and in e-mail?
     
    Alf P. Steinbach, Apr 20, 2007
    #5
  6. kostas

    kostas Guest

    On Apr 20, 1:18 pm, "Alf P. Steinbach" <> wrote:
    > However, it shouldn't be difficult to create a workaround at the design
    > level

    Thanks for the response, but i wish i could use this design.
    After all it's only a slight variation of a well known pattern.
     
    kostas, Apr 20, 2007
    #6
  7. kostas

    Ian Collins Guest

    Alf P. Steinbach wrote:
    > * kostas:
    >
    >> On Apr 20, 12:47 pm, "Alf P. Steinbach" <> wrote:
    >>
    >>> I failed to find anything about it in the standard, but adding the magic
    >>> word "class" before "Derived" seems to do the trick.

    >>
    >>
    >> if you mean this:
    >> template<class T>
    >> class Derived:public Base<T, Derived>
    >> {
    >> public:
    >> Derived(T x):Base<T, class Derived>(x){}
    >>
    >> };
    >>
    >> it doesn't work for me(gcc 3.4.4 or 4.1.1)
    >> what compiler do you use?

    >
    >
    > MSVC 7.1, but now that I checked it with Comeau Online it's evidently an
    > MS extension, not kosher, so no wonder I didn't find it in the standard.
    >

    Did Comeau Online complain about the original?

    --
    Ian Collins.
     
    Ian Collins, Apr 20, 2007
    #7
  8. kostas

    Ian Collins Guest

    Ian Collins wrote:
    > Alf P. Steinbach wrote:
    >
    >>* kostas:
    >>
    >>>On Apr 20, 12:47 pm, "Alf P. Steinbach" <> wrote:
    >>>
    >>>>I failed to find anything about it in the standard, but adding the magic
    >>>>word "class" before "Derived" seems to do the trick.
    >>>
    >>>if you mean this:
    >>>template<class T>
    >>>class Derived:public Base<T, Derived>
    >>>{
    >>>public:
    >>> Derived(T x):Base<T, class Derived>(x){}
    >>>
    >>>};
    >>>
    >>>it doesn't work for me(gcc 3.4.4 or 4.1.1)
    >>>what compiler do you use?

    >>
    >>MSVC 7.1, but now that I checked it with Comeau Online it's evidently an
    >>MS extension, not kosher, so no wonder I didn't find it in the standard.
    >>

    >
    > Did Comeau Online complain about the original?
    >

    OK, I realise why the original should not compile now. I've used this
    construct before with Sun CC, so I guess it's a compiler bug that lets
    it compile!

    --
    Ian Collins.
     
    Ian Collins, Apr 20, 2007
    #8
  9. kostas

    Zeppe Guest

    kostas wrote:
    > Hi all


    Hi!


    > template<class T>
    > class Derived:public Base<T, Derived>
    > {
    > Derived(T x):Base<T, Derived>(x){}
    > };
    >
    > the problem is that in the Base ctor call (from within Derived ctor)
    > the Derived parameter is not recognized as class template. Old gcc
    > versions(3.3.3) could cope with this, but not any more. Other
    > compilers have also problem.
    >
    > So is it a language or a compiler issue?


    I think it's a language issue, even if I haven't read carefully the
    standard to prove it :)

    > Do you know some workaround?


    What do you think about:

    template<class T>
    class Derived:public Base<T, Derived>
    {
    Derived(T x):Base<T, ::Derived>(x){}
    };

    In this way according to me you are explicitly referring to the template
    class and not the specific specialization Derived<T>.

    Regards,

    Zeppe
     
    Zeppe, Apr 20, 2007
    #9
  10. kostas

    kostas Guest

    On Apr 20, 2:26 pm, Zeppe
    <> wrote:
    > What do you think about:
    >
    > template<class T>
    > class Derived:public Base<T, Derived>
    > {
    > Derived(T x):Base<T, ::Derived>(x){}
    >
    > };
    >
    > In this way according to me you are explicitly referring to the template
    > class and not the specific specialization Derived<T>.


    Thanks a lot. It works.
    I think it also makes sense. So I hope it's not just another magic.
     
    kostas, Apr 20, 2007
    #10
  11. kostas

    Ian Collins Guest

    Zeppe wrote:
    >
    > What do you think about:
    >
    > template<class T>
    > class Derived:public Base<T, Derived>
    > {
    > Derived(T x):Base<T, ::Derived>(x){}
    > };
    >
    > In this way according to me you are explicitly referring to the template
    > class and not the specific specialization Derived<T>.
    >

    Nice one!

    --
    Ian Collins.
     
    Ian Collins, Apr 20, 2007
    #11
  12. kostas

    Guest

    On Apr 20, 5:16 am, kostas <> wrote:
    > Hi all
    > I encountered a problem testing a variation of CRTP.
    > (It's also proposed in "C++ Templates: The Complete Guide" byVandevoorde, Josuttis. See the MoreCurious template class in 16.3)
    >
    > template<class T, template <typename> class D>
    > class Base
    > {
    > protected:
    > Base(T x): i(x) {}
    >
    > T i;
    >
    > };
    >
    > template<class T>
    > class Derived:public Base<T, Derived>
    > {
    > Derived(T x):Base<T, Derived>(x){}
    >
    > };
    >
    > the problem is that in the Base ctor call (from within Derived ctor)
    > the Derived parameter is not recognized as class template. Old gcc
    > versions(3.3.3) could cope with this, but not any more. Other
    > compilers have also problem.
    >
    > So is it a language or a compiler issue?


    It's a language issue: Using the unqualified name "Derived" finds the
    injected class name, which can only be used to denote a type name (not
    a bare template name; although you can append the template arguments).

    > Do you know some workaround?



    Yes, use a qualified name. In your example, use "::Derived", as in:

    Derived(T x):Base<T, ::Derived>(x){}

    I hope that helps,

    Daveed
     
    , Apr 23, 2007
    #12
    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. sean
    Replies:
    1
    Views:
    597
    Cowboy \(Gregory A. Beamer\)
    Oct 20, 2003
  2. =?Utf-8?B?UnlhbiBTbWl0aA==?=

    Quick Question - Newby Question

    =?Utf-8?B?UnlhbiBTbWl0aA==?=, Feb 14, 2005, in forum: ASP .Net
    Replies:
    4
    Views:
    662
    Iain Norman
    Feb 16, 2005
  3. =?Utf-8?B?YW5kcmV3MDA3?=

    question row filter (more of sql query question)

    =?Utf-8?B?YW5kcmV3MDA3?=, Oct 5, 2005, in forum: ASP .Net
    Replies:
    2
    Views:
    950
    Scott Allen
    Oct 6, 2005
  4. Philip Meyer
    Replies:
    0
    Views:
    425
    Philip Meyer
    Nov 30, 2003
  5. Bit Byte
    Replies:
    1
    Views:
    854
    Teemu Keiski
    Jan 28, 2007
Loading...

Share This Page