方法std::basic_string::substr
具有参数pos, count
,指定位置 [pos,pos + count + 1] 中元素的逻辑范围。相反,大多数标准库函数(例如,std::for_each
)都有一些参数,其形式类似于begin, end
,指定范围 [begin,end]
这似乎是一个例外,然后让一些人感到困惑(请参阅问题here,here,here和here)。为什么这里没有采用通常的范围惯例?另请注意,std::vector::erase
是另一个随机访问容器的方法, 遵循惯例。
答案 0 :(得分:5)
一个简单的猜测:
你引用的不同方法有不同的行为,这可能是为什么有些人使用迭代器而其他方法没有。
std::for_each
是通用的 - 使用适用于任何容器(甚至原始数组)的方法的泛型版本的最简单方法是使用迭代器。
std::vector::erase
是SequenceContainer概念的一部分,因此它必须具有可用于任何类型容器的“通用”形式(您可以使用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
不同,后者属于erase
,std::vector
,...)和返回std::list
1 (不是迭代器,你在这里用迭代器做什么?)。
std::basic_string
中还有其他“非泛型”(即某些概念不是强制性的)方法,通常是std::basic_string
方法的整个系列,find
有一个重载insert
,size_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() );