Я прочитал прекрасную статью о семантике перемещения в С++ 11. Эта статья написана очень интуитивно. Примерный класс в статье приведен ниже.
class ArrayWrapper
{
public:
// default constructor produces a moderately sized array
ArrayWrapper ()
: _p_vals( new int[ 64 ] )
, _metadata( 64, "ArrayWrapper" )
{}
ArrayWrapper (int n)
: _p_vals( new int[ n ] )
, _metadata( n, "ArrayWrapper" )
{}
// move constructor
ArrayWrapper (ArrayWrapper&& other)
: _p_vals( other._p_vals )
, _metadata( other._metadata )
{
other._p_vals = NULL;
}
// copy constructor
ArrayWrapper (const ArrayWrapper& other)
: _p_vals( new int[ other._metadata.getSize() ] )
, _metadata( other._metadata )
{
for ( int i = 0; i < _metadata.getSize(); ++i )
{
_p_vals[ i ] = other._p_vals[ i ];
}
}
~ArrayWrapper ()
{
delete [] _p_vals;
}
private:
int *_p_vals;
MetaData _metadata;
};
Ясно, что в вышеперечисленной реализации конструктора перемещения движение не происходит для внедренного элемента _metadata
. Чтобы облегчить это, нужно использовать метод std::move()
, подобный этому.
ArrayWrapper (ArrayWrapper&& other)
: _p_vals( other._p_vals )
, _metadata( std::move( other._metadata ) )
{
other._p_vals = NULL;
}
До сих пор так хорошо.
В стандарте говорится:
§5 (С++ 11 §5 [expr]/6):
[Примечание: выражение представляет собой значение x, если оно:
результат вызова функции, неявно или явно, чей тип возврата является ссылкой rvalue на тип объекта,
приведение к ссылке rvalue на тип объекта,
выражение доступа к члену класса, обозначающее нестатический элемент данных не ссылочного типа, в котором выражение объекта является значением x, или
a
.*
выражение "указатель-к-член", в котором первый операнд является xvalue, а второй операнд - указатель на элемент данных.
Мой вопрос:
Теперь переменная other
в конструкторе перемещения является xvalue (я прав?). Тогда, согласно последнему правилу выше, other._metadata
также должно быть значением x. И, следовательно, компилятор может неявно использовать конструктор перемещения класса _metadata
. Поэтому здесь не нужно std::move
.
Что мне не хватает?