我正在解析一个将字符串作为const std::string&
参数的函数中的 std::string,在遇到空格后获取字符串的其余部分对我来说很有用。我想在该阶段存储对字符串尾部的引用,并使用它来避免复制字符串。
我在 for 循环中有一个 switch 语句,用于迭代字符串,我需要在其中一个case
标签中获取 ref。问题是你不能重新分配给参考 AFAIK,并且在案例中声明参考也是非法的。此外,我还需要开关外的 ref。
下面是一个简化的示例:
#include <string>
bool isValid(const std::string &s)
{
unsigned int length {s.length()};
for (unsigned int i {0}; i < length; ++i)
{
switch s[i]
{
// whatever other cases
case ' ':
const std::string &tail {s.substr(i, length - i};
break;
default:
// whatever
}
if (tail == "abcd")
// do something
}
}
我不知道到底会发生什么,因为我几乎是一个C++新手,但是如果我不使用 ref,我只想节省堆上的副本和分配成本。
我想存储对字符串尾部的引用
std::string &
是对字符串的引用。它不是对字符串一部分的引用。
这就是std::string_view
的用途:
const std::string_view tail =
std::string_view(s).substr(i, std::string_view::npos);
在 C++17 之前,您可以简单地使用一对迭代器:
auto substr_beg = s.begin() + i;
auto substr_end = s.end();
引用我想在该阶段存储对字符串尾部的引用,并使用它来避免复制字符串。
是对象的别名,因此不存在对std::string
对象的一部分的引用。您可以创建一个新的子字符串,例如,在发布时std::string::substr
:
const std::string &tail {s.substr(i, length - i};
请注意,这是有效的,因为const
限定引用延长了临时引用的生存期,这里的返回值为 s.substr(...)
,但很奇怪。
一种更干净的方法是首先传递一个std::string_view
,这完全是为这样的用例量身定制的,并使用std::string_view::substr
来提取字符串部分的新视图。这更有效(因为不必复制缓冲区(和惯用语。
#include <string_view>
bool isValid(const std::string_view &s)
{
// ...
const std::string_View tail = s.substr(i, length - i);
}