cplusplus / cplusplus/draft

Unclearly defined rule in [over.match.funcs#general-5] conflicts with the rule defined in [dcl.init.ref#5.2]

Open
#4,751 2 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

cwg
Dominant language
TeX
Stars
221
Forks
813
Avg merge
16h 4m
Merged PRs (30d)
36

Description

struct A{
    A() = default;
    A(volatile const A&){}
    void show()const volatile {}  // its implicit object parameter is of type volatile const A&
};
volatile A a;
A b = std::move(a);  //1 ill-formed
std::move(a).show(); //2 ok

Since prescribed in [dcl.init.ref#5.2]

Otherwise, if the reference is an lvalue reference to a type that is not const-qualified or is volatile-qualified, the program is ill-formed.

"//1" is definitely ill-formed. However, according to [over.match.funcs#general-4], the implicit object parameter should be volatile const A&, the parameter type is basically the same as that of "//1" chosen. Presumably,[over.match.funcs#general-5] gives the privilege, that is

For non-static member functions declared without a ref-qualifier, even if the implicit object parameter is not const-qualified, an rvalue can be bound to the parameter as long as in all other respects the argument can be converted to the type of the implicit object parameter.

Since there is not an exception expound in [dcl.init.ref#5.2], it appears to me that the conflict would be resulted in by [over.best.ics#general-1], that is

The sequence of conversions is an implicit conversion as defined in [conv], which means it is governed by the rules for initialization of an object or reference by a single expression ([dcl.init], [dcl.init.ref]).

My proposal is that we should first change [dcl.init.ref#5.2] to that

Otherwise, if the reference is an lvalue reference to a type that is not const-qualified or is volatile-qualified, unless somewhere specified, the program is ill-formed.

Back to [over.match.funcs#general-5], I think that the expound "in all other respects" is unclear, I think it should be modified as the following so that will be more clear

For non-static member functions declared without a ref-qualifier, even if the implicit object parameter is not const-qualified or is volatile-qualified, or both, an rvalue can be bound to the parameter as long as their referenced types are reference-compatible.

In terms of the original [over.match.funcs#general-5], for instance

struct Test{
    void show(){}
};
Test const t;
std::move(t).show(); // ill-formed

It is not fine for explaining this example.

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Compare the examples against [dcl.init.ref#5.2], [over.match.funcs#general-4/5], and [over.best.ics#general-1], focusing on how volatile references and implicit object parameters are treated. Done means the interaction is resolved with wording or interpretation that consistently explains both examples and removes the reported conflict.

Written by the indexing model from the issue text.

Assessment

Tech stack
cpp
Domain
compilers
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.