为什么 std::basic_string::substr 不遵循 [begin, end) 约定?
Why doesn't std::basic_string::substr follow the [begin, end) convention?
方法std::basic_string::substr
有参数pos, count
,指定位置[pos, pos + count + 1)中的元素的逻辑范围。相反,大多数标准库函数(例如,std::for_each
)都有与begin, end
类似形式的参数,指定范围[begin, end]
这似乎是一个例外,让一些人感到困惑(参见这里,这里,这里和这里的问题)。为什么这里没有使用通常的范围约定?还要注意std::vector::erase
,另一个随机访问容器的方法,遵循通常的约定。
标准库有多个来源,其中之一就是STL。它带来了begin,end
大会。std::string
在STL合并到标准库之前就出现了,并且有很多现有的代码使用了.substr(pos,length)
。
一个简单的猜测:
你引用的不同方法有不同的行为,这可能就是为什么有些方法使用迭代器而有些方法不使用的原因。
std::for_each
是泛型的——拥有一个在任何容器(甚至是原始数组)上工作的方法的泛型版本最简单的方法是使用迭代器。
std::vector::erase
是SequenceContainer概念的一部分,所以它必须有一个"通用"的形式,可以在任何类型的容器上工作(你可以使用pos
和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());
}
这只能工作,因为std::...::erase
是为任何SequenceContainer定义的。
另一方面,std::basic_string::substr
只是std::basic_string
的一部分(不像erase
是std::vector
, std::list
,…的一部分),并返回std::basic_string
1(不是迭代器,在这里你会用迭代器做什么?)
在std::basic_string
中还有其他"非泛型"(即某些概念不是强制性的)方法,通常是find
方法的整个家族,insert
与size_type
, append
等有过载。
从主观角度来看,我认为最好有一个不像其他容器那样行为的std::basic_string
,因为它不是(我不确定标准是否要求std::basic_string
是SequenceContainer
或类似的东西)。
1这里不能返回迭代器,因为你想要一个新的std::basic_string
,所以你会有一个接受迭代器但返回对象的方法…我觉得这比用pos
/count
代替first
/last
更令人不安。
我不能说为什么,我不在那里,但是对于您错过的[begin, end]约定,有一个范围构造函数。
template< class InputIt >
basic_string( InputIt first, InputIt last,
const Allocator& alloc = Allocator() );
- 来自 std::list 的迭代器 .end() 按预期返回"0xcdcdcdcdcdcdcdcd"但 .begin()
- std::map<struct,struct>::find 找不到匹配项,但是如果我循环通过 begin() 到 end(),我在那里看到匹配项
- remove(str.begin(), str.end(), );无法正常工作(我正在使用视觉工作室 2012)
- 了解向量中的 .begin 和 .end
- C++ const char with .begin() and .end()
- 为什么 std::find( s.begin(), s.end(), val ) 比集合 s 的 s.find(val) 慢 1000 倍<int>?
- 如何使用vector.begin()和vector.end()遍历矩阵?
- 如何实现 cbegin() 和 cend() 从 begin() 和 end() ?
- C++ - 空的 std::list begin() 和 end() 不相等
- 为什么std::begin()和std::end()适用于固定数组,而不适用于动态数组
- C++代码"x.erase(std::remove(x.begin(), x.end(), ), x.end())"是如何工作的?
- begin(),end()和cbegin(),cend()之间的区别是什么?
- 在模板化数据结构上调用 begin() 或 end()
- 重载 std::begin() 和 std::end() 用于非数组
- 使用 std::set 的 .begin() 和 .end() 函数会产生意想不到的结果
- 使用范围V3视图来实现begin()/end()方法
- 为 C++ 选择 begin() 和 end()
- 为什么"begin/end"与"first/last"的差异?
- Empty std::vector begin != end
- 匹配可迭代类型(具有begin()/end()的数组和类)