写入std :: string是否合法?

时间:2009-04-17 15:07:00

标签: c++ string standards

在std :: string中只有const成员来获取像c_str()这样的数据。但是我可以通过operator[]获得对字符串的第一个元素的引用,我可以写信给它。

例如,如果我有功能:

void toupper(char *first,char *last_plus_one);

我可以直接写入vector获取指向第一个元素的指针:

vector<char> message // has "Some Message";
toupper(&message[0],&message[0]+message.size());

我可以用std :: string做同样的事吗?

string message="Some Message";
toupper(&message[0],&message[0]+message.size());

标准是否保证内存的位置实际上是线性的?即:

&(*(message.begin()+n)) == &message[n]

感谢。

5 个答案:

答案 0 :(得分:22)

Herb Sutter这样说(http://herbsutter.wordpress.com/2008/04/07/cringe-not-vectors-are-guaranteed-to-be-contiguous/#comment-483):

  

当前的ISO C ++确实需要&amp; str [0]来连接一个指向连续字符串数据的指针(但不一定是空终止的!),所以实现者没有太多的余地来拥有非连续的字符串,无论如何。对于C ++ 0x,我们已经采用了保证std :: string内容必须连续存储。有关详细信息,请参阅http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#530

马特·奥斯特恩在引用的文件(http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#530)中也有类似的说法。

所以,似乎你可以假设一旦调用str [0]就会得到一个可修改的字符数组(但请注意,它不需要以null结尾)。

答案 1 :(得分:17)

std :: string将需要具有新的c ++ 0x标准的连续存储。目前这是未定义的行为。

答案 2 :(得分:5)

是的,您可以修改字符串。

您也可以在使用迭代器的算法中使用它。

您不能以与矢量&lt;&gt;相同的方式使用它因为不能保证元素在连续的存储位置(但是:很快就会达到你附近的标准)。

因此,如果你修改你的方法来使用迭代器而不是指针它应该工作。而且因为迭代器的行为与指针非常相似,所以代码更改应该可以忽略不计。

template<typename I>
void toupper(I first,I last_plus_one)
{
    // Probably the same code as you had before.
}


{
     std::string  s("A long string With Camel Case");

     toupper(s.begin(),s.end());
}

答案 3 :(得分:3)

正如已经指出的那样,可以在使用迭代器的算法中使用字符串;使用std::transform Ex可以实现相同的情况: - 考虑将字符串's'转换为小写:

int (*pf)(int)=tolower; //lowercase
std::transform(s.begin(), s.end(), s.begin(), pf); 

此致

答案 4 :(得分:-1)

我认为它会给你一个未定义的行为。使用字符串流写入,然后使用str()成员获取流的字符串。