为何MSVC下使用std::views::split结合std::from_chars编译失败?
MSVC中std::views::split配合std::from_chars编译失败的解决方案
问题重现
以下代码在GCC中可正常编译运行,但在MSVC中编译失败:
#include <iostream> #include <ranges> #include <string> #include <charconv> int main() { std::string source{"10%15%20%35"}; for ( auto i : source | std::views::split('%') ) { int x; std::from_chars( i.begin().base(), i.end().base(), x ); std::cout << x << ' '; } }
尽管cppreference指出P2210R2提案为std::views::split的迭代器新增了base()成员函数,且MSVC 19.31及以上版本宣称支持该提案,但实际编译仍出现问题。
解决方法
改用std::ranges::data和std::ranges::size获取子范围的字符指针和长度,替代直接调用迭代器的base():
#include <iostream> #include <ranges> #include <string> #include <charconv> int main() { std::string source{"10%15%20%35"}; for ( auto const& sub : source | std::views::split('%') ) { int x; const char* first = std::ranges::data(sub); const char* last = first + std::ranges::size(sub); std::from_chars(first, last, x); std::cout << x << ' '; } }
同时确保MSVC编译时启用了C++20或更高版本的标准(编译选项添加/std:c++20或/std:c++latest)。
原因说明
MSVC对P2210R2提案中base()函数的实现可能存在兼容性细节问题,导致直接调用迭代器base()无法正确转换为std::from_chars所需的const char*类型。而std::ranges::data和std::ranges::size是C++20范围库中获取连续范围起始地址和长度的标准接口,能在各主流编译器中保持一致的行为,避免依赖特定迭代器的实现细节。
内容的提问来源于stack exchange,提问作者Andrew
相关产品推荐
相关产品推荐

