我可以在循环中引用 std::string 的一部分并将其放在外面吗?



我正在解析一个将字符串作为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);
}

最新更新