Topic: Proposal: Semantic Change on Operator "::
Author: shang@corp.mot.com (David (Lujun) Shang)
Date: Fri, 11 Sep 92 17:38:23 GMT Raw View
[Purpose]
Eliminate the ambiguity of the operator "::" currently used in C++.
[The Existing Problem]
Two kinds of meaning are associated with operator "::" in the current C++:
(1) "::" as a selection operator:
class::name // name is a component of the class.
This expression is commonly used in accessing a nested class and
a static member.
Example1:
class A { public: static int i; };
int i = A::i;
Note that a static member can also be accessed through an object,
Therefore, "i" can be viewed as a component both of a class and of
an instance of this class.
Example2:
class A { public: class B {}; };
A::B ab;
where "A::B" means that "B" is a component class of class "A".
(2) "::" as a scope resolution operator:
::name // name is defined in global scope
class::name // name is defined in this class or its super
Example1:
class A { public: int i; };
class B: public A { public: int i; };
B b;
b.A::i;
where "A::i" suggests that "i" is defined in class "A",
but "i" is not the component of "A", instead, it is the component
of object "b". Therefore, in expression "b.A::i", the selector of
"i" is "b" and "A" is only the scope resolute of "i".
Example2:
class A { public: void foo (); };
void A::foo () {...};
where "A::foo" suggest "foo" is defined in class "A" ( Note that
"foo" is not the compnent of class "A", it belongs to an instance
of class A).
The problem is that we can not always distinguish the real role of operator
"::" in an expression.
[Ambiguity Examples]
class A { public: static int i; };
class B: public A { public: static A A; };
What is the meaning of the expression "B::A::i"? If we consider
the first "::" as the scope resolutor, "B::A::i" means the interger
"i" defined in the base class. But if we consider the first "::" as
a selector, the expression denotes the integer defined the component
object A which is defined in class B.
Thoung in fact the integer "i" is unique in this case, but how about
the following example:
class A { public: static int i; };
class A_ { public: static int i; };
class B: public A { public: static A_ A; };
Now "B::A::i=100" will have different effect if we explain "::" in
different meaning. Further, if we consider expression:
B b;
b.A::i =100;
Which "i" should get the value "100"? It depends on whether "::" is
a selector or a scope resolute.
Example2
class A { public: class NA {}; };
class B: public A
{ public:
class A { public: class NA{}; };
};
What is the meaning of the expression "B::A::NA"?
We can set up a rule to avoid the ambiguity: whenever the ambiguity
happens, we apply the scope resolute meaning to the operator "::". (In
fact, the langauge implementation has already apply this rule to solve
the ambiguity problem.). Therefore, "b.A::i" is the interger defined
in class A, not the interger of the component A, i.e. the integer of
class A_.
But how about if the user wants the selector meaning rather than the scope
resolute? For example, in expression "B::A::NA", I actually mean the class NA
nexted in class A nested in class B, not the NA nested in global class A. And
unfortuenately, this the common case. ( And the langage implementation apply
the reverse rule for this case: whenever the ambiguity happens, we apply the
selector meaning to the operator "::".)
What a chaos!
[Solution]
We use "::" only as a scope resolute. Whenever a selector must be used, use
operator ".". Then we come to a clear solution.
In example:
class A { public: static int i; };
class A_ { public: static int i; };
class B: public A { public: static A_ A; };
B b;
"B.A::i" denotes the integer of A_;
"B::A.i" denotes the integer of A;
Note that a static member is also a member of the object, therefer,
"b.A::i" denotes the integer of A;
"b.A.i" denotes the integer of A_;
In example:
class A { public: class NA {}; };
class B: public A
{ public:
class A { public: class NA{}; };
};
"B.A::NA" denotes the NA nested in global class A (i.e. A.NA)
"B.A.NA" denotes the NA nested in nested class A in B;
Nested class cannot be accessed through objects.
[Syntatic Modification]
qualified-name
constrained-name
constrained-name . qualified-name
constrained-name
:: simple-name
simple-name :: constrained-name
simple-name
identifier
(qualified-name)
Note that simple-name can be a parenthesized qualified name. Thus we can have
the expression like:
C.NC.(BC1.NBC)::BBC1::NBBC
to denote a nested class NBBC in the following class definitions:
class BBC1
{ public:
class NBBC {};
};
class BBC2
{ public:
class NBBC {};
};
class BC1
{ public:
class NBC: public BBC1, public BBC2 {};
};
class BC2
{ public:
class NBC: public BBC1, public BBC2 {};
};
class C
{ public:
class NC: public BC1.NBC, public BC2.NBC {};
};
David Shang
Author: shang@corp.mot.com (David (Lujun) Shang)
Date: Fri, 11 Sep 92 18:24:05 GMT Raw View
In article <1992Sep11.173823.17289@cadsun.corp.mot.com> shang@corp.mot.com
(David (Lujun) Shang) writes:
> In example:
>
> class A { public: static int i; };
> class A_ { public: static int i; };
> class B: public A { public: static A_ A; };
> B b;
>
> "B.A::i" denotes the integer of A_;
> "B::A.i" denotes the integer of A;
>
Sorry, should be
"B.A.i" denotes the integer of A_;
"B.A::i" denotes the integer of A;
Note that "::" has a hihger priority than ".".
David Shang