Is it legal to modify the result of std::string::op[]?
我想交换char *和std :: string的内容而不能这样做。经过上述链接后,我仍然无法得到我的问题的答案。
这是我正在尝试做的事情,并且无法成功地使用char *交换字符串。代码在VS2010上验证。
更新1 所有的努力都是为了看看我是否能获得任何表现并且没有获得任何SO点数。 :-)
更新2 我在评论中提到了为什么我打算这样做。人们是否还认为这需要暂停?
void Swap(char* const& left, char* const& right)
{
std::swap(const_cast<char*>(left), const_cast<char*>(right));
}
std::string ToString()
{
std::string ret(1, ' ');
char* str = new char[6]();
strcpy(str, "Jagan");
Swap(&ret[0], str);
return ret;
}
答案 0 :(得分:2)
是的,正如您在链接的帖子中看到的那样,您可以修改string[x]
的值,前提是x >= 0 && x < string.size()
但标准非常清楚您可以't 修改其他任何东西(你当然不能将&string[x]
作为有效的指向可修改的空终止字符串传递 - 记住string.c_str()
和{{1 }}返回string.data()
。
但是,您可以实施:
const char*
答案 1 :(得分:1)
所有代码&ret[0]
都会创建一个临时变量,它是指向ret
中字符的指针。对swap
的调用将此临时变量设置为指针str
,并将str
设置为此临时变量。结果是ret
不受影响,并且您在str
中泄漏了内存。为了更清楚,此代码等同于
char* str = new char[6]();
strcpy(str, "Jagan");
char* tmpPtr = &ret[0]
Swap(tmpPtr, str);
所以你可以看到tmpPtr
的末尾等于str
的原始值。您根本无法访问char*
中的内部str
指针。这是故意,因为更广泛的问题是你为什么要这样做?即使你可以分配给str
的内部指针,这样做将违反封装 - 例如,您假设内部指针是使用new
分配的。但是stl容器可以 - 并且确实 - 使用它们自己的内部分配机制,并且应该可以在将来更改它们的实现而不会破坏客户端代码。正如您可以在没有客户的情况下更改班级的实施情况一样。代码破坏。
答案 2 :(得分:1)
无法完成。
std::string
没有提供替换其内部数据指针的标准方法。
实际上,并非std::string
的所有实现都始终具有指向使用new[]
分配的以零终止的字符块的指针。你不应该知道,如果你发现了(信息隐藏/实现隐藏),你当然不应该依赖它。
不同的std::string
实现可能会执行以下任何操作:
char *
分开。除经典C字符串外,std::string
的实例允许包含空字符。std::strings
之间共享参考计数。你不想干涉这里。char [16]
,用于短字符串而不是堆指针这就是为什么当您想要与自己管理的std::string
交换时,您仍然无法复制char*
的内容。
答案 3 :(得分:0)
你所做的事情在很多层面都是错误的。
要将std::string
与char *
指向的手动管理字符串“交换”,您需要手动管理该字符串,如:
std::string one = ...;
char *two = ...;
// swap:
std::string tmp = two;
delete[] two;
two = new char[one.size() + 1];
memcpy(two, one.c_str(), one.size() + 1);
one = tmp;