C++20中用views::split结果构造std::string报错的问题咨询
问题原因与解决方法:C++20 views::split构造std::string报错
错误原因
你尝试使用std::string(rng.begin(), rng.end())构造字符串时,调用的是C标准中传统的双迭代器构造函数,该构造函数要求传入的迭代器必须满足「遗留输入迭代器(LegacyInputIterator)」的规范。但std::views::split返回的子范围的迭代器是C20新增的范围迭代器,并不符合遗留迭代器的要求,因此编译器无法找到匹配的构造函数,从而触发C2440和E0289错误。
正确实现方式
方式1:使用C++20 std::string范围构造函数(推荐)
C++20为std::basic_string新增了接受符合std::ranges::input_range要求的范围的构造函数,可以直接用views::split返回的子范围构造std::string:
#include <string> #include <vector> #include <ranges> int main() { std::string source = "apple,banana,orange"; std::vector<std::string> parts; // 遍历split后的每个子范围 for (auto&& sub_range : source | std::views::split(',')) { // 直接用子范围构造std::string,添加到vector parts.emplace_back(sub_range); } return 0; }
方式2:用std::ranges::copy拷贝内容(兼容旧C++20实现)
如果你的编译器对范围构造函数的支持不完善,可以通过std::ranges::copy将子范围的字符拷贝到新的std::string中:
#include <string> #include <vector> #include <ranges> #include <algorithm> #include <iterator> int main() { std::string source = "apple,banana,orange"; std::vector<std::string> parts; for (auto&& sub_range : source | std::views::split(',')) { std::string part; // 将子范围的字符拷贝到part中 std::ranges::copy(sub_range, std::back_inserter(part)); parts.push_back(part); } return 0; }
补充说明
std::views::split返回的每个子范围是std::ranges::subrange类型,它直接引用原字符串中的字符,没有额外拷贝。使用上述两种方式构造std::string时,才会将子范围的字符拷贝到新的字符串对象中,符合你的需求。
内容的提问来源于stack exchange,提问作者DoItWithFlow
相关产品推荐
相关产品推荐

