tags:

views:

51

answers:

2

Basically this is what I'd like to do:

struct A {
    enum E {
        X, Y, Z
    };
};

template <class T>
struct B {
    using T::E;
};

// basically "import" the A::E enum into B.
std::cout << B<A>::X << std::endl;

The reason why is that I want to basically inject the implementation details into my template class. At the same time, the enum of the "model" reflects information that I want the user to be able to have for a particular instantiation of a template. Is this possible?

I know that I could have B inherit from A, but I think that isn't an ideal solution because I want to be able to add new "models" without changing the guts of B.

EDIT: Now that I've though about it, inheritance doesn't necessarily need to be ruled out. Perhaps the following is ideal:

struct A {
    enum E {
        X, Y, Z
    };
};

template <class T>
struct B : A {
};

int main() {
    std::cout << B<A>::X << std::endl;
}
+1  A: 

I think you can do

template <class T>
struct B {
    typedef typename T::E E;
};
ArunSaha
that creates an instance of the enum. I want to basically "import" the enum type itself into the scope of `B`
Evan Teran
@Evan Teran: Got it after your comment. I made an edit to fit to your requirement.
ArunSaha
+2  A: 

This works for me:

struct A {
    enum E {
        X, Y, Z
    };
};

template <class T>
struct B {
    typedef typename T::E E;
};

// basically "import" the A::E enum into B.
int main(void)
{
    std::cout << B<A>::E::X << std::endl;
    return 0;
}

Output is

0

I do get a warning about non-standard extension in that qualified name so perhaps there is a more elegant solution.

Steve Townsend
Anyway to get rid of that intermediate `::E` in that `cout` statement?
Evan Teran
And it doesn't seem to work with gcc 4.5.1: `error: 'B<A>::E' is not a class or namespace`
Evan Teran
@Evan - :-) will let you know, I imagine so... see edited version (last line). I am on Visual C++ v10
Steve Townsend
@Steve: i think you have the best non-inheritance solution, So I'm giving you the accept. But now that I think about it, inheritance with templates may be perfect for what I need. See my edit of my question.
Evan Teran
@Steve: That won't compile under C++03, since an `enum` is not a true type. You can change the `typedef` in `B` to: `typedef T E` and get the same usage, though.
Travis Gockel
@Evan - yes, that looks good. @Travis - trying to test this, did you lose something in code formatting? Please feel free to edit my answer if you wish.
Steve Townsend