`=`赋值给新的std::string到底赋值了什么?
What exactly is assigned by the `=` assigment to the new std::string?
我想写一个方法,应该 trim 一个 std::string 的持续和尾随白色 spaces。例如,如果方法得到“HELLO WORLD”,它应该return“HELLO WORLD”。请注意,return 字符串之间是一个白色的 space,这很重要。
这是我方法的签名:
std::string MyHandler::Trim(const std::string& toTrim)
我的方法是将 'toTrim' 参数复制到一个非常量副本中。
std::string toTrimCopy = toTrim;
现在我想得到一个非常量迭代器并在 for 循环中从头到尾擦除任何白色space,而迭代器值是白色 space.
for (std::string::iterator it = toTrim.begin(); *it == ' '; it++)
{
toTrimCopy.erase(it);
}
for (std::string::iterator it = toTrim.end();
*it == ' ';
it--)
{
toTrimCopy.erase(it);
}
这导致编译器错误:
StringHandling.C:60:49: error: conversion from ‘std::basic_string<char>::const_iterator {aka __gnu_cxx::__normal_iterator<const char*, std::basic_string<char> >}’ to non-scalar type ‘std::basic_string<char>::iterator {aka __gnu_cxx::__normal_iterator<char*, std::basic_string<char> >}’ requested
我来自Java,我现在学习 C++ 3 周了。所以不要评判我。我怀疑 =
赋值将常量 char 指针分配给我的新字符串,因此我的副本隐含了一个常量值。不过我也不是很清楚。
顺便说一句,这种方法也会抛出异常:
std::string toTrimCopy = "";
std::strcpy(toTrimCopy, toTrim);
他说,他无法将字符串转换为字符指针。
将迭代器从 toTrim
传递给 toTrimCopy
的方法是未定义的行为,所以你很幸运,类型不匹配捕获了它。
std::string::begin
有两个重载:
std::string::iterator std::string::begin();
std::string::const_iterator std::string::begin() const;
字符串的const
ness参与重载决议。您不能从 const_iterator
初始化 iterator
,因为这将允许您通过该迭代器修改基础对象。
我会把你的功能改成
namespace MyHandlerNS { // optional, could be in global namespace
std::string Trim(std::string toTrim) {
for (auto it = toTrim.begin(); it != toTrim.end() && *it == ' ';) {
it = toTrim.erase(it);
}
for (auto it = toTrim.rbegin(); it != toTrim.rend() && *it == ' ';) {
it = toTrim.erase(it.base());
}
return toTrim;
}
}
或者使用标准算法完全摆脱循环
#include <algorithm>
namespace MyHandlerNS { // optional, could be in global namespace
std::string Trim(std::string toTrim) {
auto isSpace = [](char c){ return c == ' '; };
auto it = std::find_if_not(toTrim.begin(), toTrim.end(), isSpace);
toTrim.erase(toTrim.begin(), it);
it = std::find_if_not(toTrim.rbegin(), toTrim.rend(), isSpace).base();
toTrim.erase(it, toTrim.end());
return toTrim;
}
}
我终于决定使用正则表达式了:
std::string StringHandling::Trim (const std::string& toTrim)
{
return std::regex_replace(toTrim, std::regex("^ +| +$"), "");
}
线程可以在这里关闭。
我想写一个方法,应该 trim 一个 std::string 的持续和尾随白色 spaces。例如,如果方法得到“HELLO WORLD”,它应该return“HELLO WORLD”。请注意,return 字符串之间是一个白色的 space,这很重要。
这是我方法的签名:
std::string MyHandler::Trim(const std::string& toTrim)
我的方法是将 'toTrim' 参数复制到一个非常量副本中。
std::string toTrimCopy = toTrim;
现在我想得到一个非常量迭代器并在 for 循环中从头到尾擦除任何白色space,而迭代器值是白色 space.
for (std::string::iterator it = toTrim.begin(); *it == ' '; it++)
{
toTrimCopy.erase(it);
}
for (std::string::iterator it = toTrim.end();
*it == ' ';
it--)
{
toTrimCopy.erase(it);
}
这导致编译器错误:
StringHandling.C:60:49: error: conversion from ‘std::basic_string<char>::const_iterator {aka __gnu_cxx::__normal_iterator<const char*, std::basic_string<char> >}’ to non-scalar type ‘std::basic_string<char>::iterator {aka __gnu_cxx::__normal_iterator<char*, std::basic_string<char> >}’ requested
我来自Java,我现在学习 C++ 3 周了。所以不要评判我。我怀疑 =
赋值将常量 char 指针分配给我的新字符串,因此我的副本隐含了一个常量值。不过我也不是很清楚。
顺便说一句,这种方法也会抛出异常:
std::string toTrimCopy = "";
std::strcpy(toTrimCopy, toTrim);
他说,他无法将字符串转换为字符指针。
将迭代器从 toTrim
传递给 toTrimCopy
的方法是未定义的行为,所以你很幸运,类型不匹配捕获了它。
std::string::begin
有两个重载:
std::string::iterator std::string::begin();
std::string::const_iterator std::string::begin() const;
字符串的const
ness参与重载决议。您不能从 const_iterator
初始化 iterator
,因为这将允许您通过该迭代器修改基础对象。
我会把你的功能改成
namespace MyHandlerNS { // optional, could be in global namespace
std::string Trim(std::string toTrim) {
for (auto it = toTrim.begin(); it != toTrim.end() && *it == ' ';) {
it = toTrim.erase(it);
}
for (auto it = toTrim.rbegin(); it != toTrim.rend() && *it == ' ';) {
it = toTrim.erase(it.base());
}
return toTrim;
}
}
或者使用标准算法完全摆脱循环
#include <algorithm>
namespace MyHandlerNS { // optional, could be in global namespace
std::string Trim(std::string toTrim) {
auto isSpace = [](char c){ return c == ' '; };
auto it = std::find_if_not(toTrim.begin(), toTrim.end(), isSpace);
toTrim.erase(toTrim.begin(), it);
it = std::find_if_not(toTrim.rbegin(), toTrim.rend(), isSpace).base();
toTrim.erase(it, toTrim.end());
return toTrim;
}
}
我终于决定使用正则表达式了:
std::string StringHandling::Trim (const std::string& toTrim)
{
return std::regex_replace(toTrim, std::regex("^ +| +$"), "");
}
线程可以在这里关闭。