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

Ami*_*ory 2 c++ string range substr

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

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

Hol*_*olt 5

一个简单的猜测:

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

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

std::vector::eraseSequenceContainer概念的一部分,所以它必须有一个"通用"形式,可以在任何类型的容器上工作(你可以使用poscount一个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());
}
Run Code Online (Sandbox Code Playgroud)

这只能起作用,因为std::...::erase它可以为任何SequenceContainer定义良好.

在另一方面,std::basic_string::substr是一个只有一部分std::basic_string(不同于erase这是一部分std::vector,std::list......),并返回一个std::basic_string1(不迭代器,你会用一个迭代器在这里做什么?).

还有其他的"非一般"(即不通过一些概念强制性的)方法std::basic_string,通常全家人的find方法,insert具有过载size_type,append等.

在一个主观的观点上,我认为最好std::basic_string不要像其他容器那样表现,因为它不是(我不确定标准要求std::basic_stringSequenceContainer什么或类似的东西).

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


MSa*_*ers 5

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