Name resolution not working as expected

I was trying something (which is now obsolete due to some new understandings of templates I changed my mind, I still may need something like this to reduce code duplication in a certain case), but was wondering why this occurred anyway and if it is a bug.

I have a global var (m) with an initial value 5.

I have a template class (A) that derives from a either a base class that has a member (_A1.m) or not (_A0), based upon it's template parameter. class (A) has a member function (fn) returns the value of (m) as it understands what (m) is.

However, this gives different results compared with a non-template class in a similar scenario. I'm expecting that if derived from _A1, that m should be taken from the base class scope and if derived from _A0, it should be taken from the global one.

Here is the code for your amusement:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
int m = 5;

class _A0
{
        public:
                _A0(int)
                {
                }
};

class _A1
{
        public:
                int m;
                _A1(int m)
                        : m(m)
                {
                }
};

template <class T>
class A : public T
{
        public:
                A(int m)
                : T(m)
                {
                }

                A()
                {}

                int fn()
                {
                        return m;
                }
};

class _B1
{
        public:
                int m;
                _B1(int m)
                        : m(m)
                {
                }
};

class B1 : public _B1
{
        public:
                B1(int m)
                        : _B1(m)
                {
                }

                int fn()
                {
                        return m;
                }
};

class _B0
{
        public:
                _B0(int)
                {
                }
};

class B0 : public _B0
{
        public:
                B0(int m)
                        : _B0(m)
                {
                }

                int fn()
                {
                        return m;
                }
};

int main()
{
        A<_A1> a1(3);
        B1 b1(3);
        A<_A0> a0(3);
        B0 b0(3);
        cout << "Global value of m is:  " << m << endl;
        cout << "B0 class has no internal m member.  Object resolves m internally with value " << b0.fn() << endl;
        cout << "B1 class has    internal m member.  Object resolves m internally with value " << b1.fn() << endl;
        cout << "A<_A0> class has no internal m member.  Object resolves m internally with value " << a0.fn() << endl;
        cout << "A<_A1>  class has    internal m member.  Object resolves m internally with value " << a1.fn() << endl;
        return 0;
}


This compiled using g++ 4.5.3 and 4.6.3 with the same results:
Global value of m is:  5
B0 class has no internal m member.  Object resolves m internally with value 5
B1 class has    internal m member.  Object resolves m internally with value 3
A<_A0> class has no internal m member.  Object resolves m internally with value 5
A<_A1>  class has    internal m member.  Object resolves m internally with value 5


Now can someone tell me if this is a bug or some other artifact?
Last edited on
The compiler works correctly. Let consider for example class B1. It is a non-template class. Its base class has member m which initialized by the constructor to 3 in declaration

B1 b1( 3 );

member function fn() displays the value of data member m that is equal to 3.

Now consider class B0. It is also a non-template class. Neither it nor its base class have a data member with the name m. So member function fn() will display global variable m.

Now consider class A. It is a template class. It knows nothing what data members has its base class because the base class is set by the template parameter, So in function fn() it uses global variable m that is displayed. If you want that it will be the data member of the base class you should write the function fn() the following way

1
2
3
4
               int fn()
                {
                        return T::m;
                }


Last edited on
Now consider class A. It is a template class. It knows nothing what data members has its base class because the base class is set by the template parameter...


Yes, but I thought that is what the templating system was supposed to do, allow for auto generation of classes/functions at the time of instantiation given the types/non-types specified. I would think that would require to look through what was inherited. On the other hand, I guess it could generate some off the wall, hard to track down bugs.

I guess I can see the reasoning for it.

Is there a way for the templating system to stipulate scope? Might be possible using a nested template class. Hmmmmm.
Last edited on
Topic archived. No new replies allowed.