Edit: I'm using tdm-gcc-4.7.1-2 for Windows
Not sure how to resolve this. I'd like to use this as a sort of type list that will let me know I'm attempting to use a type not present in B's typedefs.
template <typename T, typename U>
struct A {
typedef pair<T, U> type;
};
struct B : A<int, string>, A<int, float> {};
B::type foo; // won't compile, ambiguous reference, as expected
B::A<int, int>::type bar; // compiles fine?? :(
Is there a way to get it to fail on A<int, int> (and any other A's not inherited by B), or another way to go about this? I guess I could use a tuple and recurse my way through it, doing an is_same comparison on each element vs whatever I feed the metafunction, but this seemed easier... at first :\
This happens because class templates have their template-name injected; the injected name can be used either as a template or a type referring to the template instantiation (14.6.1p1). The injected class name is then inherited by the derived class (10.2p5); using it as a template is unambiguous (it's the same template however it is inherited) so is allowed.
To fix your program, try using is_base_of:
struct B : A<int, string>, A<int, float> { };
template<typename T, typename U>
using check_A = typename std::enable_if<std::is_base_of<A<T, U>, B>::value, A<T, U>>::type;
check_A<int, float>::type bar1; // compiles
check_A<int, int>::type bar2; // error
In §11.1/5, the Standard says:
In a derived class, the lookup of a base class name will find the injected-class-name instead of the name of the base class in the scope in which it was declared. The injected-class-name might be less accessible than the name of the base class in the scope in which it was declared.
So A is an injected name in the scope of B. It refers to the template A, not the base class (because it would be ambiguous) according to §14.1/4.
Just like in the scope of A, if you say just A, it's the class itself (but it's the template in this context). You're making use of this injected name, and so the name B::A is the same as ::A. I don't think there's a way to suppress this behaviour.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With