为什么无法通过std::string的迭代器构造std::string_view对象?
std::string_view迭代器区间构造问题解答
报错的核心原因
你查到的template<class It, class End> constexpr basic_string_view(It first, End last) 构造函数是C++20才新增的特性,如果编译时使用的是C++17及更早的标准,标准库没有提供这个构造函数,自然会编译报错。
该构造函数对迭代器的支持范围
这个构造函数不限制为仅支持std::basic_string_view自身的迭代器,只要满足以下约束就可以使用:
- 迭代器
It满足contiguous_iterator(连续迭代器)要求 - 哨兵类型
End满足sized_sentinel_for<It>要求 - 迭代器指向的元素类型与
basic_string_view的字符类型匹配
std::string的迭代器完全符合上述要求,只要你开启C20及更高的编译标准,你注释掉的代码是可以正常编译运行的。如果开启C20后仍然报错,检查编译器版本:GCC 10+、Clang 12+、MSVC 2019 16.10+均已完整支持该特性。
C++17及更低版本的零开销替代方案
不需要构造临时std::string子串,有两种零开销的实现方式:
- 直接通过指针和长度构造:
std::string_view strSubView{str.data(), 2};
- 先构造全串的
std::string_view,再调用它的substr方法(std::string_view的substr是O(1)操作,不会产生任何拷贝):
std::string_view strView{str}; std::string_view strSubView = strView.substr(0, 2);
为什么C++17没有提供这个构造函数
C17首次引入std::string_view时,还没有正式的contiguous_iterator概念定义,无法对构造函数的入参做约束,如果允许任意迭代器传入,很容易出现传入非连续迭代器导致的未定义行为。直到C20完善了迭代器概念体系后,才新增了这个受约束的迭代器区间构造函数。
内容的提问来源于stack exchange,提问作者Const
相关产品推荐
相关产品推荐

