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

嵌套闭包传递std::array编译失败:是否违反C++标准?

嵌套闭包场景下std::array类模板实参推导的编译问题

问题场景

给定如下前置声明:

#include <array>

template <typename V> void makeError(V& v) {}

以下代码在MSVC 16.11.13(/std:c++17)编译失败:

int main() {
    [&]() {
        std::array bugs{0};
        [&]() { makeError(bugs); };
    };
    return 0;
}

报错信息:

main.cpp(9,5): error C2955: 'std::array': use of class template requires template argument list

但相同代码在GCC 10.4(--std=c++17)中可正常编译。

另外,移除内层闭包或外层闭包后的代码:

// 移除内层闭包
int main() {
    [&]() {
        std::array bugs{0};
        makeError(bugs);
    };
    return 0;
}
// 移除外层闭包
int main() {
    std::array bugs{0};
    [&]() { makeError(bugs); };
    return 0;
}

在MSVC和GCC中均能正常编译。

问题解答

这段代码是有效的C++17代码,MSVC的报错属于编译器实现缺陷,而非代码违反C++标准。

原因分析

  1. 类模板实参推导(CTAD)规则:C17引入的类模板实参推导允许编译器根据初始化器自动推导类模板的模板参数。对于std::array bugs{0};,编译器应当推导出模板参数为int(元素类型)和1(数组大小),即实际类型为std::array<int, 1>,这符合C17标准[temp.deduct.class]章节的规定。
  2. 编译器实现差异:只有在嵌套闭包的场景下,MSVC未能正确完成外层闭包中std::array变量的CTAD推导,而GCC正确处理了该场景。移除任意一层闭包后两边都能编译,说明这是MSVC在处理嵌套闭包时的推导逻辑漏洞,而非代码本身不符合标准。

内容的提问来源于stack exchange,提问作者Joshua Hyatt

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 11:41:04