CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 4 of 4
  1. #1
    Join Date
    Sep 2010
    Posts
    2

    NOT WORK: <class T>void foo(const typename T::ENUM&)

    I want a function template parameterized with a parent class, but deduced from an internal type (in this case, an enum):

    class MyParent {
    public:
    enum MyEnum {
    MY_ENUM_A,
    MY_ENUM_B,
    };
    void foo(MyEnum my_enum) {
    //...
    }
    static const MyParent& GetInstance(void) {
    static const MyParent INSTANCE_;
    return INSTANCE_;
    }
    };

    template <class SOME_PARENT>
    void SomeFunc(const typename SOME_PARENT::SOME_ENUM& some_enum)
    {
    SOME_PARENT::GetInstance().foo(some_enum);
    }

    // THE ACTUAL CALL TO USE IT:
    SomeFunc(MyParent::MY_ENUM_A); // <--C2783, could not deduce template argument
    SomeFunc<MyParent>(MyParent::MY_ENUM_A); // <--C2770, invalid explicit template argument
    -------------------------------

    Bummer ... can't I use "typename" somewhere or other bit of trickery? I realize the nested type is only an "enum" (not a real type), and I don't want to promote it to a "bigger" type with a handle to the parent class. Rather, I'd like to parameterize with the parent type, where I can use the parent type to establish a "context" to process the nested enumeration.

    The goal, of course, is to merely call "SomeFunc()" with a mere enumerated value (would be so elegant if it worked ...)

    Suggestions?

    (sorry, can't figure out how to insert preformatted code snippets)

  2. #2
    Join Date
    Oct 2008
    Posts
    1,456

    Re: NOT WORK: <class T>void foo(const typename T::ENUM&)

    Quote Originally Posted by charleyb View Post
    (sorry, can't figure out how to insert preformatted code snippets)
    use [ code ] [ / code ] ( without spaces, of course )

    Quote Originally Posted by charleyb View Post
    The goal, of course, is to merely call "SomeFunc()" with a mere enumerated value
    you can write

    Code:
    template <class T> struct EnumParent {};
    
    class MyParent
    {
    public:
    	enum MyEnum
    	{
    		MY_ENUM_A,
    		MY_ENUM_B,
    	};
    };
    
    template <> struct EnumParent<MyParent::MyEnum> { typedef MyParent type; };
    
    template <class T>
    void SomeFunc( T some_enum  )
    {
    	// EnumParent<T>::type is the parent type; note that this function will give an error if T
    	// has not been previously "registered" with an EnumParent specialization.
    	// More specifically, if you have more then one SomeFunc overload you'll need to setup a
    	// SFINAE context to make type deduction fail ( you can do it manually or through boost::enable_if )
    }
    if needed, you can put a further check in EnumParent ( or SomeFunc ) through boost or tr1 type trait is_enum<T>.

  3. #3
    Join Date
    Sep 2010
    Posts
    2

    Re: NOT WORK: <class T>void foo(const typename T::ENUM&)

    AWESOME! THANKS!

    I really scratched my head on that one, but it makes complete sense now that I see it.

    Compiles, I'm sure it will work, but it will take a couple days for me to confirm (I'm in the middle of a large root canal with this propagated interface change).

    Thanks again!

  4. #4
    Join Date
    Apr 2004
    Location
    Canada
    Posts
    1,342

    Re: NOT WORK: <class T>void foo(const typename T::ENUM&)

    Note that you can get your original version to work if you provide the enumeration name in the function declaration (SOME_PARENT::MyEnum instead of SOME_PARENT::SOME_ENUM) and you provide the template parameter SOME_PARENT explicitly:

    Code:
    class MyParent {
    public:
    enum MyEnum {
    MY_ENUM_A,
    MY_ENUM_B,
    };
    void foo(MyEnum my_enum) {
    //...
    }
    static const MyParent& GetInstance(void) {
    static const MyParent INSTANCE_;
    return INSTANCE_;
    }
    };
    
    template <class SOME_PARENT>
    void SomeFunc(const typename SOME_PARENT::MyEnum& some_enum)
    {
    SOME_PARENT::GetInstance().foo(some_enum);
    }
    
    ...
    // Call site
    SomeFunc<MyParent>(MyParent::MY_ENUM_A);
    Old Unix programmers never die, they just mv to /dev/null

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