[conv.mem] p2 should specify the complete conversion path
Nobody has claimed this yet.
- Dominant language
- TeX
- Stars
- 221
- Forks
- 813
- Avg merge
- 16h 4m
- Merged PRs (30d)
- 36
Description
Consider the example in [expr.eq] p4.6
struct B {
int f();
};
struct L : B { };
struct R : B { };
struct D : L, R { };
int (B::*pb)() = &B::f;
int (L::*pl)() = pb;
int (R::*pr)() = pb;
int (D::*pdl)() = pl;
int (D::*pdr)() = pr;
bool x = (pdl == pdr);
The relevant rule says
Otherwise, two pointers to members compare equal if they would refer to the same member of the same most derived object or the same subobject if indirection with a hypothetical object of the associated class type were performed, otherwise they compare unequal.
We expect that the result of pdl can clearly be that refers to D's L's instance of B, and pdr refers to D's R's instance of B, hence they don't refer to the member of the same subobject and are not equivalent. The result of the conversion is completely expressed in [conv.mem] p2. However, [conv.mem] p2 cannot well express the result in the case that multi-converts the pointer to a member to pointer to the derived classes' member. The current wording is
The result of the conversion refers to the same member as the pointer to member before the conversion took place, but it refers to the base class member as if it were a member of the derived class. The result refers to the member in D's instance of B.
[conv.mem] p2 can well tell the story that pl refers to the member in L's instance of B. However, we expect [conv.mem] p2 can also well define that pdl refers to the member in D's L's instance of B, in this case, the rule is hard to read out this meaning. The suggestion to the current wording might be:
A prvalue of type “pointer to member of B of type cv T”, where B is a class type, can be converted to a prvalue of type “pointer to member of D of type cv T”, where D is a complete class derived ([class.derived]) from B.
.... The result of the conversion refers to the hypothetical memberMDof classDof typecv T; any reference toMDrefers to the member ofM(B)ofD. For classB,M(B)is defined as follows.
- If the pointed member of
Bis a hypothetical member that is invented for converting the prvalue of type “pointer to member of C of type cv T” to “pointer to member of B of type cv T”,M(C)ofB.- otherwise,
B; the declaring-base-class.Since the result has type “pointer to member of D of type cv T”, indirection through it with a D object is valid. The result is the same as if indirecting through the pointer to member of
Uthat is the declaring-base-class with the base class subobjectM(B)ofD. The null member pointer value is converted to the null member pointer value of the destination type.
After this suggestion, the result of pdl is clear to interpret. pdl refers to the hypothetical member of class D, and such a reference results in pdl referring to the M(L) of D, where M(L) is B of L. The result of pdl is the member of B of L of D, which completely tells conversions in the path.
Not a completely formal suggestion, just one thought that can clarify the result in the conversion path.
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with [conv.mem] p2 and compare its wording with the pointer-to-member example in [expr.eq] p4.6. Trace the multi-step conversion path through pdl and pdr, then revise the standard wording so each intermediate base subobject is unambiguous and the example's comparison result follows directly.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- cpp
- Domain
- documentation
- Issue type
- Documentation
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 25/100