为什么std :: basic_string :: substr不遵循[begin,end]约定?

时间:2016-09-28 05:50:50

标签: c++ string range substr

方法std::basic_string::substr具有参数pos, count,指定位置 [pos,pos + count + 1] 中元素的逻辑范围。相反,大多数标准库函数(例如,std::for_each)都有一些参数,其形式类似于begin, end,指定范围 [begin,end]

这似乎是一个例外,然后让一些人感到困惑(请参阅问题herehereherehere)。为什么这里没有采用通常的范围惯例?另请注意,std::vector::erase是另一个随机访问容器的方法, 遵循惯例。

3 个答案:

答案 0 :(得分:5)

一个简单的猜测:

你引用的不同方法有不同的行为,这可能是为什么有些人使用迭代器而其他方法没有。

std::for_each是通用的 - 使用适用于任何容器(甚至原始数组)的方法的泛型版本的最简单方法是使用迭代器。

std::vector::eraseSequenceContainer概念的一部分,因此它必须具有可用于任何类型容器的“通用”形式(您可以使用pos和{{1} }对于count,但是std::vector还是std::list呢?拥有这样的概念对于创建通用代码非常有用:

std::set

这只能起作用,因为template <typename C> void real_remove(C &c, const typename C::value_type &value) { c.erase(std::remove(c.begin(), c.end(), value), c.end()); } 已为任何SequenceContainer定义良好。

另一方面,std::...::erase只是std::basic_string::substr的一部分(与std::basic_string不同,后者属于erasestd::vector,...)和返回std::list 1 (不是迭代器,你在这里用迭代器做什么?)。

std::basic_string中还有其他“非泛型”(即某些概念不是强制性的)方法,通常是std::basic_string方法的整个系列,find有一个重载insertsize_type等等。

在主观观点上,我认为最好让append与其他容器不同,因为它不是(我不确定标准是否需要std::basic_string成为{ {1}}或任何相似的东西)。

1 你不能在这里返回迭代器,因为你想要一个新的std::basic_string,所以你有一个方法来获取迭代器但返回一个对象...我会发现这么多比SequenceContainer / std::basic_string代替pos / count更令人不安。

答案 1 :(得分:5)

历史原因。标准库有多个来源,其中一个是STL。它带来了begin,end惯例。 std::string早于将STL合并到标准库中,并且有大量现有代码使用.substr(pos,length)

答案 2 :(得分:1)

我无法说出原因,我不在那里,但是你错过了[开始,结束]大会的范围构造函数。

template< class InputIt >
basic_string( InputIt first, InputIt last,
              const Allocator& alloc = Allocator() );