Date: Fri, 27 Mar 2020 17:10:33 -0400
Inspired by: https://stackoverflow.com/q/60893342/481267 where const
std::string& is being initialized from a string literal.
This is controlled by [dcl.init.ref]/5.4.1
<http://eel.is/c++draft/dcl.init.ref#5.4.1>:
If T1 or T2 is a class type and T1 is not reference-related to T2,
user-defined conversions are considered using the rules for
copy-initialization of an object of type “*cv1* T1” by user-defined
conversion ([dcl.init] <http://eel.is/c++draft/dcl.init>, [over.match.copy]
<http://eel.is/c++draft/over.match.copy>, [over.match.conv]
<http://eel.is/c++draft/over.match.conv>); the program is ill-formed if the
corresponding non-reference copy-initialization would be ill-formed. The
result of the call to the conversion function, as described for the
non-reference copy-initialization, is then used to direct-initialize the
reference. For this direct-initialization, user-defined conversions are not
considered.
If I read this literally, then initializing const std::string& from a
string literal should create a *cv-unqualified* temporary of type
std::string. This is because the "conversion function" called by the
corresponding non-reference copy-initialization is a constructor, and
according to [dcl.init]/17.6.3 <http://eel.is/c++draft/dcl.init#17.6.3>,
the constructor call is considered to yield a cv-unqualified prvalue which
is then used to initialize the possibly cv-qualified object.
I think that this is probably not the intended interpretation, but it is
impossible to tell for sure because the wording is not clear. I suspect
that the real intent of p5.4.1 is that the temporary is materialized with
type *cv1* T1. The reason why I say this is that p5.3 contains such a
provision explicitly. Furthermore, the C++11 wording that governs similar
initializations also says that the temporary is created with type *cv1* T1.
It would be surprising to me if the intent of p5.4.1 is to create a
cv-unqualified temporary.
I am thinking of filing a DR. Does anyone think this is not a defect? If
so, why?
std::string& is being initialized from a string literal.
This is controlled by [dcl.init.ref]/5.4.1
<http://eel.is/c++draft/dcl.init.ref#5.4.1>:
If T1 or T2 is a class type and T1 is not reference-related to T2,
user-defined conversions are considered using the rules for
copy-initialization of an object of type “*cv1* T1” by user-defined
conversion ([dcl.init] <http://eel.is/c++draft/dcl.init>, [over.match.copy]
<http://eel.is/c++draft/over.match.copy>, [over.match.conv]
<http://eel.is/c++draft/over.match.conv>); the program is ill-formed if the
corresponding non-reference copy-initialization would be ill-formed. The
result of the call to the conversion function, as described for the
non-reference copy-initialization, is then used to direct-initialize the
reference. For this direct-initialization, user-defined conversions are not
considered.
If I read this literally, then initializing const std::string& from a
string literal should create a *cv-unqualified* temporary of type
std::string. This is because the "conversion function" called by the
corresponding non-reference copy-initialization is a constructor, and
according to [dcl.init]/17.6.3 <http://eel.is/c++draft/dcl.init#17.6.3>,
the constructor call is considered to yield a cv-unqualified prvalue which
is then used to initialize the possibly cv-qualified object.
I think that this is probably not the intended interpretation, but it is
impossible to tell for sure because the wording is not clear. I suspect
that the real intent of p5.4.1 is that the temporary is materialized with
type *cv1* T1. The reason why I say this is that p5.3 contains such a
provision explicitly. Furthermore, the C++11 wording that governs similar
initializations also says that the temporary is created with type *cv1* T1.
It would be surprising to me if the intent of p5.4.1 is to create a
cv-unqualified temporary.
I am thinking of filing a DR. Does anyone think this is not a defect? If
so, why?
-- *Brian Bi*
Received on 2020-03-29 12:29:10