You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.27 02:52:12