![](/img/trans.png)
[英]vector<string> initialization with {…} is not allowed in VS2012?
[英]Move a string in vs2012
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个字符的字符串。 它做了交换(两个指针相等)。 因此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();
}
具体来说,这里发生的是“小字符串优化”。
Visual C ++的STL(以及许多其他版本)具有“胖” std::string
类,它们可以在内部保存一个小字符串,并且需要零内存分配。 这是一些常见用例的优化。
即使使用std::move
,因为你的字符串足够小,所以它完全存储在std::string
本身内部,因此必须复制。 如果您尝试使用较大的字符串,您的代码可能会起作用,但绝对不能保证它会,并且您不应该依赖于该行为。
基本上认为这些实现中的std::string
与以下类似:
class string {
// space for small strings; only used if _external is nullptr
char _local[16];
// pointer to heap-allocated memory; if nullptr, the string is stored in _local
char* _external;
// stores a string using small-string optimization is appropriate
void store(char* src) {
if (std::strlen(src) < sizeof(_local)) {
// small string, store in our local buffer and set _external to nullptr
std::strcpy(_local, src);
delete _external;
_external = nullptr;
} else if (src != _external) {
// large string, allocate space in heap
delete _external;
_external = new char[std::strlen(src) + 1];
std::strcpy(_external, src);
}
}
public:
// assign a C string to this string
string(char* src) : _external(nullptr) { store(src); }
string& operator=(char* src) { store(src); return *this; }
// be sure to properly use either _local or _external pointer
char* c_str() { return _external ? _external : _local; }
bool empty() const { return c_str()[0] == 0; }
};
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.