2

In a situation like this, why can't I access the base class member x unqualified in the B1 case? Doesn't loook ambiguous to me…

template<class T>
struct A { T x; };

template<class T>
struct B1 : A<T> { T f() { return A<T>::x; } };

struct B2 : A<int> { int f() { return x; } };
pascal
  • 2,623
  • 2
  • 20
  • 30

1 Answers1

3

Because x is not dependent, it will be looked up in the context where the template is defined. In that context, the compiler knows nothing of T, and cannot look in dependent base classes. How can it, for example, know anything of A<T> without knowing what T is. (There could be a specialization of A for example, with completely different members.)

James Kanze
  • 150,581
  • 18
  • 184
  • 329
  • This doesn't explain *why* the compiler cannot see `x`. The base class isn't `T`, it's `A`, and the definition of `A` is already available when `B1` is defined. I know the language doesn't work that way, but the question, as I read it, is "why doesn't it?" –  Apr 05 '13 at 11:57
  • Actually, I think the question here is more about why it can't see `x` given that we *know* the base type is `A`. No template arguments here at all. – Joseph Mansfield Apr 05 '13 at 11:58
  • The base class is dependent on `T`. The compiler cannot see it until it knows what `T` is. (What if `A` is explicitly specialized for some types, for example?) – James Kanze Apr 05 '13 at 12:04
  • @sftrabbit When we know that the base class is `A`, it can see `x`, and there is no problem. When all that is known is that it is `A`, then the compiler cannot know what `A` contains until it knows what `T` is. – James Kanze Apr 05 '13 at 12:06
  • @JamesKanze Oh, I totally misread the question. – Joseph Mansfield Apr 05 '13 at 12:08
  • @JamesKanze Right. And that comment has the bit that should be part of the answer, I think, as that explains *why* the compiler cannot see `A`'s definition even though it looks like it's right there. –  Apr 05 '13 at 12:18
  • But a specialized `A` couldn't *remove* members? That's why I thought it was weird that I couldn't access `x` since we know it will be there for all `T`s. – pascal Apr 05 '13 at 14:17
  • 1
    @pascal When you specialize `A`, you can do pretty much whatever you want. If you want an example, look in the standard: `std::allocator` has less than half the members of the generic `std::allocator`. – James Kanze Apr 05 '13 at 17:53