Clang报推导返回类型函数未定义错误,GCC可编译,谁符合C++23标准?
C++23代码在GCC与Clang的编译分歧问题
以下C++23代码可在GCC中正常编译并输出预期结果,但在Clang中编译失败:
#include <array> #include <tuple> constexpr auto makeNumberGenerator = [](this auto maker, int startingValue) { return [maker, startingValue]<typename Generator>(this Generator generator) -> std::tuple<int, Generator> { return std::make_tuple(startingValue, maker(startingValue + 1)); }; }; auto test = []{ std::array<int, 5> arr; auto fn = [](this auto self, int* output, const int* end, auto callable) -> void { auto [value, newCallable] = callable(); if (output != end) { *output = value; self(output + 1, end, newCallable); } }; fn(std::begin(arr), std::end(arr), makeNumberGenerator(0)); return arr; }();
编译结果
编译参数为-O2 -std=c++23:
- GCC编译输出:
test: .long 0 .long 1 .long 2 .long 3 .long 4 - Clang编译错误:
<source>:9:47: error: function 'operator()<(lambda at <source>:5:38)>' with deduced return type cannot be used before it is defined 9 | return std::make_tuple(startingValue, maker(startingValue + 1)); | ^ <source>:8:5: note: while substituting into a lambda expression here 8 | { | ^ <source>:26:59: note: in instantiation of function template specialization '(anonymous class)::operator()<(lambda at <source>:5:38)>' requested here 26 | fn(std::begin(arr), std::end(arr), makeNumberGenerator(0)); | ^ <source>:5:38: note: 'operator()<(lambda at <source>:5:38)>' declared here 5 | constexpr auto makeNumberGenerator = [](this auto maker, int startingValue) | ^ 1 error generated. Compiler returned: 1
核心疑问
该代码是否符合C++23标准?GCC与Clang哪个的行为是正确的?
编辑补充
编辑1:修复后可兼容两款编译器的代码
修改如下代码后,代码可在GCC和Clang中均编译通过:
constexpr auto makeNumberGenerator = [](this auto self, int startingValue) { return std::bind([startingValue](auto maker) { return std::make_tuple(startingValue, maker(startingValue + 1)); }, self); };
若将std::bind替换为普通Lambda,仍会触发原错误。
编辑2:问题与deducing this特性无关
以下未使用deducing this特性的代码,同样出现GCC可编译、Clang报错的情况:
#include <array> #include <tuple> constexpr auto makeNumberGenerator = [](auto maker, int startingValue) { return [maker, startingValue]<typename Generator>(Generator generator) -> std::tuple<int, Generator> { return std::make_tuple(startingValue, maker(maker, startingValue + 1)); }; }; auto test = []{ std::array<int, 5> arr; auto fn = [](auto self, int* output, const int* end, auto callable) -> void { auto [value, newCallable] = callable(callable); if (output != end) { *output = value; self(self, output + 1, end, newCallable); } }; fn(fn, std::begin(arr), std::end(arr), makeNumberGenerator(makeNumberGenerator, 0)); return arr; }();
内容的提问来源于stack exchange,提问作者LHLaurini
相关产品推荐
相关产品推荐

