std::string t1("aaa");
const char *p = t1.c_str();
std::string t2(std::move(t1));
if (p == t2.c_str()) {
std::cout << "ok!" << std::endl;
}
このコードは、vs2012 では何も出力しませんでした。文字列をにmemmove
コピーするために内部的に使用するだけです。なんで?t1
t2
正式には、jrok が指摘したように、あなたがしていることは未定義の動作であるため、実装が何を行っても文句を言う権利はありません。実際には、実装に依存します。標準では、移動コンストラクターがstd::string
ソース文字列に関して何かを行う必要はありません。実装が小さな文字列の最適化を使用し (たとえば、VC++ がそうであるように)、文字列が修飾するのに十分小さい場合、文字を memcpy する以外に何もする方法はありません
。彼らはchar[]
文字列オブジェクト自体。CoW の実装 (g++ のようなもの) は、わざわざする価値がないという理由で、コピー コンストラクターで行うことと何も変わらないかもしれません。あなたは本当に多くを節約しません。(しかし、ポインターを交換するだけで少し節約できるので、そうなるかもしれません。)
VC++で同じことを試しましたが、文字列は100文字です。それはスワップを行いました(そして2つのポインタは等しかったです)。したがって、VC++ の動作は、文字列が SSO を適用するのに十分小さいかどうかによって異なります。すべてのケースで G++ スワップ。
Visualtudioは実際にポインターを移動する前に文字列の長さを比較し、std::move
コードにデバッグすることで、長さの文字列をコピーしたことが16バイト未満であることを示しています
void _Assign_rv(_Myt&& _Right)
{
// assign by moving _Right
if (_Right._Myres < this->_BUF_SIZE) //_BUF_SIZE is 16, comment mine
_Traits::move(this->_Bx._Buf, _Right._Bx._Buf,
_Right._Mysize + 1);
else
{ // copy pointer
this->_Getal().construct(&this->_Bx._Ptr, _Right._Bx._Ptr);
_Right._Bx._Ptr = pointer();
}
this->_Mysize = _Right._Mysize;
this->_Myres = _Right._Myres;
_Right._Tidy();
}