Re: members of r value references and copy constructors
On Apr 2, 9:36 am, Brendan wrote:
Are members of r value references also considered r values?
References have no members. If you mean the members of an object
that's an rvalue expression: yes, the accessed member will also be an
rvalue expression. Example:
struct foo {
string s;
};
void bar(string const&); // #1
void bar(string &&); // #2
int main() {
bar(foo().s); // --> #2
}
In particulate, consider this Image class.
typedef unsigned char Byte;
typedef std::vector<Byte> ImageVec;
struct Image {
[...]
Image(Image&& img):
m_data(img.m_data),
m_width(img.m_width),
m_height(img.m_height){
img.m_width = 0;
img.m_height = 0;
}
Oh, I see, you're talking about NAMED rvalue references ...
I'm wondering if the move constructor here can be expected to move the
data from img.m_data to m_data, if I need to rewrite that as:
m_data(std::move(img.m_data))
img is a named reference. As such it's an lvalue expression.
img.m_data will therefore also be an lvalue expression. So, either use
std::move here or simply don't write any copy/move operations and the
destructor yourself.
Similarly, do I need to use std::move in the move assignment operator.
While the answer to this question is "No", the answer to the question
you actually have in mind is "Yes.". Again: the name of a reference is
always an lvalue expression. Only an UNNAMED rvalue reference
(returned from a function) is an rvalue.
Anyhow, it is perfectly reasonable to use a "unified assignment
operator" in many cases:
Image& Image&::operator=(Image temp_copy)
{
this->swap(temp_copy);
return *this;
}
You don't see any std::move here. So, it's not necessary ;-)
Technically, this is considered a copy assignment operator (judging by
the definition of copy assignment in the C++ standard). But in case
your class is cheaply movable, and you have a cheap swap function,
this kind of operator serves both purposes (copy assign and move
assign with just an additional but cheap move to create temp_copy).
Finally, I want to clarify my understanding of when implicit move
constructors are generated. My understanding is that this changed
during the standardization process. Could someone give a statement on
exactly when implicit move constructors are generated in the final
draft, perhaps with reference to section?
There are 6 special member functions. Without default constructor,
this leaves the following 5:
* copy ctor
* move ctor
* copy assign
* move assign
* dtor
Move operations are generated if all data members support the move
operation in question and the user DID NOT declare ANY of these 5
special member functions.
The same is true for generating copy operations with the EXCEPTION
that a user-declared copy operation or user-declared dtor DOES NOT YET
stop the compiler from generating remaining copy operations. This
exception is for C++98 compatibility. But it is already deprecated and
code that relies on this exception should be changed to make use of C+
+2011's "operation=default;" declarations so that it'll continue to
work in C++1y mode ;-)
Builtin types are considered to be movable by copying.
Cheers!
SG
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]