gpt4 book ai didi

c++ - 是否允许在 std::string 的实现中进行这种优化?

转载 作者:可可西里 更新时间:2023-11-01 18:27:40 29 4
gpt4 key购买 nike

我只是在考虑std::string::substr 的实现。它返回一个新的 std::string 对象,这对我来说似乎有点浪费。为什么不返回一个引用原始字符串内容并可以隐式分配给 std::string 的对象?一种对实际复制的懒惰评估。这样的类可能看起来像这样:

template <class Ch, class Tr, class A>
class string_ref {
public:
// not important yet, but *looks* like basic_string's for the most part

private:
const basic_string<Ch, Tr, A> &s_;
const size_type pos_;
const size_type len_;
};

此类的公共(public)接口(interface)将模拟真实 std::string 的所有只读操作,因此使用起来是无缝的。 std::string 然后可以有一个新的构造函数,它采用 string_ref 所以用户永远不会变得更聪明。在您尝试“存储”结果的那一刻,您最终创建了一个拷贝,因此指向数据的引用没有真正的问题,然后在背后修改它。

想法是这样的代码:

std::string s1 = "hello world";
std::string s2 = "world";
if(s1.substr(6) == s2) {
std::cout << "match!" << std::endl;
}

将总共构造不超过 2 个 std::string 对象。这似乎是对执行大量字符串操作的代码的有用优化。当然,这不仅适用于 std::string,还适用于任何可以返回其内容子集的类型。

据我所知,没有实现这样做。

我想问题的核心是:

给定一个可以根据需要隐式转换为 std::string 的类,库编写者将成员的原型(prototype)更改为返回类型是否符合标准?或者更一般地说,库编写者是否有余地在这些类型的情况下返回“代理对象”而不是常规对象作为优化?

我的直觉是这是不允许的,原型(prototype)必须完全匹配。假设您不能单独重载返回类型,那么库编写者就没有利用这些类型情况的空间。就像我说的,我认为答案是否定的,但我想我会问 :-)。

最佳答案

这个想法是 copy-on-write ,但不是 COW 整个缓冲区,而是跟踪缓冲区的哪个子集是“真实”字符串。 (COW,以其正常形式,曾经(现在?)用于某些库实现中。)

因此您根本不需要代理对象或接口(interface)更改,因为这些细节可以完全内部化。从概念上讲,您需要跟踪四件事:源缓冲区、缓冲区的引用计数以及此缓冲区中字符串的开头和结尾。

只要一个操作修改了缓冲区,它就会创建自己的拷贝(从开始和结束分隔符),将旧缓冲区的引用计数减一,并将新缓冲区的引用计数设置为一。其余的引用计数规则是相同的:复制并加一,破坏一个字符串并减一,达到零并删除等。

substr 只是创建一个新的字符串实例,除了明确指定的开始和结束分隔符。

关于c++ - 是否允许在 std::string 的实现中进行这种优化?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4682603/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com