C++ Logo

std-discussion

Advanced search

Re: C++20 unexpectedly calling const overload of constructor

From: Thiago Macieira <thiago_at_[hidden]>
Date: Wed, 11 Mar 2020 23:31:11 -0700
On Wednesday, 11 March 2020 11:11:09 PDT Rob Lefebvre via Std-Discussion
wrote:
> class MyClass
> {
> public:
> MyClass(const char (&value)[30])
> {
> std::cout << "CONST " << value << '\n';
> }
>
> MyClass(char (&value)[30])
> {
> std::cout << "NON-CONST " << value << '\n';
> }
> };
>
> MyClass test_1()
> {
> char buf[30] = "test_1";
> return buf;
> }

Your finding that the RVALUE constructor gets called is the hint. This is
happening because in the function above, by the time that the constructor for
MyClass is called, buf is an xvalue. If you change it to:

MyClass test_1()
{
    char buf[30] = "test_1";
    MyClass ret(buf);
    return ret;
}

Then the NON-CONST overload gets called: at the time of the construction, buf
is still a glvalue.

I don't know which paper exactly made the change, but I suspect it's one that
made local variables xvalues on more scenarios on return statements, such as
calling the constructor for an NRVO. Or it's the NRVO change itself.

Note this was already the case for:

std::string foo()
{
    std::string s;
    getString(&s);
    return s; // implicitly moved from
}

At the point of the return, variable s was going out of scope, so it's
implicitly an xvalue and you got the std::string(std::string &&) move
constructor. Note that this became stronger with NRVO, but the principle
applies even when the optimisation can't kick in.

-- 
Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org
   Software Architect - Intel System Software Products

Received on 2020-03-12 01:34:01