1 // Testcase for implicit 'typename' and resolution of 'typename's in the
2 // current scope.
3 
4 class base1 {
5 public:
bar()6     int bar() const
7     { return 1; }
8 };
9 
10 class base2 {
11 public:
bar()12     int bar() const
13     { return 0; }
14 };
15 
16 template<class X>
17 struct base_trait {
18     typedef base1 base;
19 };
20 
21 template<>
22 struct base_trait<float> {
23     typedef base2 base;
24 };
25 
26 template<class T>
27 class weird : public base_trait<T>::base {
28 public:
29     typedef typename base_trait<T>::base base;
30 
31     base f ();
32     int base::* g ();
33 
34     int zowee() const
35     { return bar(); }
36 };
37 
38 template <class T>
39 typename weird<T>::base weird<T>::f ()
40 {
41     return base();
42 }
43 
44 // The standard does not allow this case; the `typename' keyword may
45 // not appear in a ptr-operator.
46 #if 0
47 template <class T>
48 int typename weird<T>::base::* weird<T>::g ()
49 { return 0; }
50 #endif
51 
52 int main()
53 {
54     weird<float> z;
55     return z.zowee() || z.f().bar();
56 }
57