|
-
September 10th, 2010, 10:52 PM
#1
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)
-
September 11th, 2010, 03:04 AM
#2
Re: NOT WORK: <class T>void foo(const typename T::ENUM&)
 Originally Posted by charleyb
(sorry, can't figure out how to insert preformatted code snippets)
use [ code ] [ / code ] ( without spaces, of course )
 Originally Posted by charleyb
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>.
-
September 11th, 2010, 08:10 PM
#3
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!
-
September 13th, 2010, 03:55 PM
#4
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
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|