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