RVO?

S

Stefan Ram

I wrote

struct string
{
/* copy constructor */ string( string const & s )
{ ::std::cerr << "string( string const & )\n"; }

/* move constructor */ string( string && ) noexcept
{ ::std::cerr << "string( string && ) noexcept\n"; }

/* additional entries here */ };

and then, later:

string a{ "abc" }; []( string const s )->string{ return s; }( a );

. The statement »[]( string const s )->string{ return s; }( a );« printed

string( string const & )
string( string const & )

. So the implementation is using the copy constructor twice,
and is not using the move constructor, even for the return?

I have expected it to use the copy constructor for parameter
initialization, but the move constructor for returning the
result.

The same with »return ::std::move( s );«.
 
V

Victor Bazarov

I wrote

struct string
{
/* copy constructor */ string( string const & s )
{ ::std::cerr << "string( string const & )\n"; }

/* move constructor */ string( string && ) noexcept
{ ::std::cerr << "string( string && ) noexcept\n"; }

/* additional entries here */ };

and then, later:

string a{ "abc" }; []( string const s )->string{ return s; }( a );

. The statement »[]( string const s )->string{ return s; }( a );« printed

string( string const & )
string( string const & )

. So the implementation is using the copy constructor twice,
and is not using the move constructor, even for the return?

I have expected it to use the copy constructor for parameter
initialization, but the move constructor for returning the
result.

The same with »return ::std::move( s );«.

I don't know the semantics and requirements for 'std::move', but AFA
returning a value from a function by giving it the argument goes, I
think you're expecting too much from the compiler. The constructed
temporary (which is passed to the function as its argument) has to
survive until the end of the expression in which it's constructed. The
compiler can't move its contents to the return value because the
argument should then be destroyable, and it isn't. But I'm probably out
of my depth anyway...

V
 
M

Marc

Stefan said:
I wrote

struct string
{
/* copy constructor */ string( string const & s )
{ ::std::cerr << "string( string const & )\n"; }

/* move constructor */ string( string && ) noexcept
{ ::std::cerr << "string( string && ) noexcept\n"; }

/* additional entries here */ };

and then, later:

string a{ "abc" }; []( string const s )->string{ return s; }( a );

. The statement »[]( string const s )->string{ return s; }( a );« printed

string( string const & )
string( string const & )

. So the implementation is using the copy constructor twice,
and is not using the move constructor, even for the return?

I have expected it to use the copy constructor for parameter
initialization, but the move constructor for returning the
result.

The same with »return ::std::move( s );«.

Your parameter has type "string const", emphasis on the "const" here.
Without a const_cast, it has no reason to drop the const. If you had a
string(string const&&) constructor, it could use that.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,776
Messages
2,569,603
Members
45,201
Latest member
KourtneyBe

Latest Threads

Top