CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 13 of 13
  1. #1
    Join Date
    Jan 2009
    Posts
    19

    Question self-referencing policies

    Hello,
    I've just discovered policy based design (due to a forum topic a few days ago) and am having fun playing around with it. Here's a little question I ran into: I want my policy class to have a convenient label for the datatype inherent to its derived class. Here's my bare-bones example:

    Code:
    template<class T>
    class policy{
    public:
      typedef typename T::fooType fooType;
    };
    
    template<class fooType>
    class foo : public policy<foo<fooType> >{
    };
    
    int main(){
      foo<int> F;
      return 0;
    }
    This doesn't compile (gcc v4.1), because at the time the typedef is evaluated by the compiler, foo is not yet fully defined. Any ideas how to get around this? I know I could nix the typedef and use T::fooType explicitly, but that gets very messy in my "real world" example...

  2. #2
    Join Date
    Apr 2007
    Location
    Mars NASA Station
    Posts
    1,436

    Re: self-referencing policies

    I think forward declaration may off the compile error.
    Thanks for your help.

  3. #3
    Join Date
    Nov 2008
    Location
    England
    Posts
    748

    Re: self-referencing policies

    Did you expect it to compile?

    The compiler is looking for int::fooType and theres no such animal.
    Get Microsoft Visual C++ Express here or CodeBlocks here.
    Get STLFilt here to radically improve error messages when using the STL.
    Get these two can't live without C++ libraries, BOOST here and Loki here.
    Check your code with the Comeau Compiler and FlexeLint for standards compliance and some subtle errors.
    Always use [code] code tags [/code] to make code legible and preserve indentation.
    Do not ask for help writing destructive software such as viruses, gamehacks, keyloggers and the suchlike.

  4. #4
    Join Date
    Jan 2009
    Posts
    19

    Re: self-referencing policies

    okay, how about this variation? I still get an error on compilation. I tried various combinations of predeclaring each class, but they don't seem to do the trick.
    Code:
    template<class T>
    class policy{
    public:
      typedef typename T::fooType fooType;
    };
    
    template<class T>
    class foo : public policy<foo<T> >{
      typedef T fooType;
    };
    
    
    int main(){
      foo<int> F;
      return 0;
    }

  5. #5
    Join Date
    May 2002
    Posts
    1,435

    Re: self-referencing policies

    Read Russco's comment again.

  6. #6
    Join Date
    Aug 2005
    Location
    LI, NY
    Posts
    576

    Re: self-referencing policies

    Quote Originally Posted by jakevdp View Post
    okay, how about this variation? I still get an error on compilation. I tried various combinations of predeclaring each class, but they don't seem to do the trick.
    Code:
    template<class T>
    class policy{
    public:
      typedef typename T::fooType fooType;
    };
    
    template<class T>
    class foo : public policy<foo<T> >{
      typedef T fooType;
    };
    
    
    int main(){
      foo<int> F;
      return 0;
    }
    This still doesn't make any sense. In order for the policy class to resolve T::fooType, T needs to be a complete type, which it can't be because at this point in the instantiation we're still evaluating its base class. This is the stuff "internal compiler error"s are made of.

    Why not just do the following:
    Code:
    template<class T>
    class policy{
    public:
      typedef T fooType;
    };
    
    template<class T>
    class foo : public policy<T>{
    };
    
    
    int main(){
      foo<int> F;
      return 0;
    }
    ?
    - Alon

  7. #7
    Join Date
    Aug 2007
    Posts
    858

    Re: self-referencing policies

    okay, how about this variation? I still get an error on compilation. I tried various combinations of predeclaring each class, but they don't seem to do the trick.
    Aside from what they've pointed out about why the typedef won't work, what you're trying to do here is just odd. Using a derived class as the template parameter for its own base class?

  8. #8
    Join Date
    Jan 2006
    Location
    Singapore
    Posts
    6,765

    Re: self-referencing policies

    Quote Originally Posted by Speedo
    what you're trying to do here is just odd. Using a derived class as the template parameter for its own base class?
    It is odd indeed. Read up on the "curiously recurring template pattern".
    C + C++ Compiler: MinGW port of GCC
    Build + Version Control System: SCons + Bazaar

    Look up a C/C++ Reference and learn How To Ask Questions The Smart Way
    Kindly rate my posts if you found them useful

  9. #9
    Join Date
    Jan 2009
    Posts
    19

    Re: self-referencing policies

    Hello,
    I found a solution - I thought I'd share it with you. This was pointed out to me by a friend, and comes from the FLENS source code (see http://flens.sourceforge.net/ ). This compiles, and creates the behavior I hoped for:

    Code:
    template <typename T>
    struct TypeInfo;
    
    template<class T>
    class policy{
    public:
      typedef typename TypeInfo<T>::Type DerivedType;
    };
    
    template<class T>
    class foo : public policy<foo<T> >{};
    
    template <typename T>
    struct TypeInfo<foo<T> >
    {
        typedef foo<T> Type;
    };
    
    int main(){
      foo<int> F;
      policy<foo<int> >& P = F; // F::DerivedType is foo<int>
      return 0;
    }
    Essentially, policy:: DerivedType is shorthand for the class that derives from it, as long as that derived type defines a TypeInfo specialization for itself. Kind of a cool trick, and useful, for returning data from a base class which is of the derived class type. This simplifies my code, anyway. Any remarks on this type of structure?

  10. #10
    Join Date
    Mar 2002
    Location
    St. Petersburg, Florida, USA
    Posts
    12,125

    Re: self-referencing policies

    Quote Originally Posted by jakevdp View Post
    Hello,
    I found a solution -
    Sounds exactly like what Peter_APIT suggested in the very first reply to your question.....a simple forward declaration of...

    Code:
    template <typename T>
    struct TypeInfo;
    TheCPUWizard is a registered trademark, all rights reserved. (If this post was helpful, please RATE it!)
    2008, 2009,2010
    In theory, there is no difference between theory and practice; in practice there is.

    * Join the fight, refuse to respond to posts that contain code outside of [code] ... [/code] tags. See here for instructions
    * How NOT to post a question here
    * Of course you read this carefully before you posted
    * Need homework help? Read this first

  11. #11
    Join Date
    May 2002
    Posts
    1,435

    Re: self-referencing policies

    Quote Originally Posted by TheCPUWizard View Post
    Sounds exactly like what Peter_APIT suggested in the very first reply to your question.....a simple forward declaration of...
    While a forward declaration may be necessary, I see that the solution found by jakevdp is substantially different from the code originally posted. The typedef was the problem then and that was addressed by Russco when he said int::fooType is not valid. It now appears to me that the original was just a very bad attempt at implementing the "curiously recurring template pattern" (as pointed out by laserlight) which has now been corrected. Is my analysis wrong?

  12. #12
    Join Date
    Apr 1999
    Location
    Altrincham, England
    Posts
    4,470

    Re: self-referencing policies

    Hang on, that doesn't do what the original post was trying to achieve. In the OP, you had policy defining a type declared within the template argument
    Code:
    template<class T>
    struct policy
    {
        typedef typename T::fooType fooType;
    };
    The one you've just posted is functionally equivalent to
    Code:
    template<class T>
    struct policy
    {
        typedef T DerivedType;
    };
    (or has the cold addled my brain, and I'm missing something obvious?)


    ETA: I see someone else has had the same thought - maybe it's not just me, then.
    Correct is better than fast. Simple is better than complex. Clear is better than cute. Safe is better than insecure.
    --
    Sutter and Alexandrescu, C++ Coding Standards

    Programs must be written for people to read, and only incidentally for machines to execute.

    --
    Harold Abelson and Gerald Jay Sussman

    The cheapest, fastest and most reliable components of a computer system are those that aren't there.
    -- Gordon Bell


  13. #13
    Join Date
    Jan 2009
    Posts
    19

    Re: self-referencing policies

    Right - thanks. The original example was trying for something like this:
    Code:
    template <typename T>
    struct TypeInfo;
    
    template<class T>
    class policy{
    public:
      typedef typename TypeInfo<T>::Type DerivedType;
    };
    
    template<class T>
    class foo : public policy<foo<T> >{};
    
    template <typename T>
    struct TypeInfo<foo<T> >
    {
        typedef T Type;
    };
    
    int main(){
      foo<int> F;
      policy<foo<int> >& P = F; // P::DerivedType is int
      return 0;
    }
    Using this, a policy object can know about any of the template parameters of a derived type. That's what I was going for.
    Last edited by jakevdp; January 5th, 2009 at 03:57 PM. Reason: typo

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured