C++20 std::ranges代码在不同编译器下的兼容性问题咨询
C++20 Ranges代码的编译器合规性判定
这段使用C++20 ranges库提取二维vector第一列的代码,在不同编译器版本中表现差异明显,以下是具体情况及合规性分析:
代码示例
#include <vector> #include <string> #include <ranges> #include <iostream> int main() { // 返回仅包含可迭代容器第i个元素的范围 auto ith_element = [](size_t i) { // 跳过前i个元素后取第一个元素 return std::views::drop(i) | std::views::take(1); }; // 返回第i列的遍历范围 auto column = [ith_element](size_t i) { return std::views::transform(ith_element(i)) | std::views::join; // 提取输入范围中每个元素的第i个元素组成新范围 }; std::vector<std::vector<std::string>> myvec = { { "a", "aaa", "aa"}, {"bb", "b", "bbbb"}, {"cc", "cc", "ccc"} }; for (auto const& v: myvec | column(0)){ std::cout << v << std::endl; } return 0; }
各编译器表现
- GCC 10.1~10.4:编译通过,但输出错误内容
b
- GCC 11.1、Clang:编译失败,报错信息如下
error: no match for 'operator|' (operand types are 'std::vector<std::vector<std::__cxx11::basic_string<char> > >' and 'std::ranges::views::__adaptor::_Pipe<std::ranges::views::__adaptor::_Partial<std::ranges::views::_Transform, std::ranges::views::__adaptor::_Pipe<std::ranges::views::__adaptor::_Partial<std::ranges::views::_Drop, long unsigned int>, std::ranges::views::__adaptor::_Partial<std::ranges::views::_Take, int> > >, std::ranges::views::_Join>')
- GCC 11.2~12.2、MSVC 19.33:编译通过,输出预期结果
a bb cc
合规性分析
这段代码通过std::views::transform结合drop+take的视图管道,再用join扁平化结果,完全符合C++20标准中ranges库的规范。
- GCC 10.x的错误输出源于早期ranges实现的bug,对视图组合的处理逻辑错位,导致元素提取错误。
- GCC 11.1和Clang的编译失败,是因为当时的版本对ranges适配器的管道组合支持不完善,无法正确解析
transform与join的复合适配类型。 - GCC 11.2+和MSVC 19.33的行为符合C++20标准,它们正确实现了ranges库中视图组合、适配的规范逻辑,能够正常编译并输出预期结果。
内容的提问来源于stack exchange,提问作者joergbrech
相关产品推荐
相关产品推荐

