std::ranges::views::transform在Clang下编译失败问题咨询
问题描述
如下简单C程序可在g(12.1.0)环境下正常编译,但在clang(14.0.6)环境下编译失败,编译器会输出篇幅极长、指向性较弱的错误信息:
#include <ranges> #include <vector> int main() { std::vector<int> v{1, 2, 3}; auto fview = std::ranges::views::transform(v, [](auto p) { return p; }); return 0; }
clang输出的核心错误提示为error: no matching function for call to '__begin',完整错误信息长达约183行,不便全部粘贴展示。
问题原因与修正
这段代码的写法本身是符合C20标准规范的:按照C20标准定义,std::ranges::views::transform作为范围适配器,原生支持两种等价调用形式:
- 直接传入待处理范围、转换函数的双参数调用形式(也就是示例代码中的写法)
- 通过
|管道运算符串联范围与适配器的调用形式
clang 14.0.6编译失败是该版本的实现缺陷导致的,和代码标准合规性无关:
- 如果你使用clang配套的libc作为标准库,14版本的libc没有完整实现transform适配器的双参数调用重载,编译器会错误匹配到内部其他实现分支,最终抛出找不到
__begin的冗长报错。 - 如果你使用clang搭配GCC 12的libstdc作为标准库编译,libstdc的ranges模块依赖了少量GCC专属的内部接口,clang 14没有做对应兼容,也会抛出同类错误。
如果需要兼容clang 14版本,只需要把双参数调用改成管道写法即可,修改后的可正常编译的代码如下:
#include <ranges> #include <vector> int main() { std::vector<int> v{1, 2, 3}; auto fview = v | std::ranges::views::transform([](auto p) { return p; }); return 0; }
额外注意:clang 14对C++20 ranges的支持属于实验性阶段,编译时需要额外添加-std=c++20 -fexperimental-library编译参数,否则还可能触发其他特性相关的编译、链接错误。
内容的提问来源于stack exchange,提问作者Reimundo Heluani
相关产品推荐
相关产品推荐

