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

GCC 11中std::array::size()无法作为常量表达式的原因

GCC 11编译失败原因解析

示例代码

#include <iostream>
#include <array>
#include <bitset>

template <class T, std::size_t N>
class Booth
{
  public:
    int function(const std::array<T, N> & data) {
        std::bitset<data.size()> bit_set{};

        return 0;
    };

  private:
};

int main()
{
    std::cout << "std::array test\n";

    std::array<int, 3> data2{2};
    Booth<int, 3> booth{};
    std::cout << booth.function(data2) << std::endl;

    return 0;
}

问题描述

这段代码在旧版GCC及OnlineGDB中可正常编译,但在GCC 11中编译失败,报错信息如下:

g++ -Wall -Wconversion -lstdc++ -pthread -std=c++17 -o array_size src/array_size.cpp
src/array_size.cpp: In function ‘int function(const std::array<int, 42>&)’:
src/array_size.cpp:22:28: error: ‘data’ is not a constant expression
   22 |     std::bitset<data.size()> bit_set{};
      |                            ^
src/array_size.cpp:22:26: note: in template argument for type ‘long unsigned int’
   22 |     std::bitset<data.size()> bit_set{};
      |                 ~~~~~~~~~^~

GCC 11的核心变更

GCC 11严格修正了常量表达式用于模板参数的检查规则,具体如下:

  • 按照C++标准,std::bitset的模板参数必须是编译期可知的常量表达式。虽然std::array::size()是constexpr成员函数,但调用它的对象data是函数形参——属于运行期才能确定的自动存储期变量,并非编译期常量表达式,因此data.size()不能作为模板实参。
  • 旧版GCC存在非标准的宽松行为,允许将这类运行期对象的constexpr成员函数调用当作常量表达式用于模板参数。GCC 11修复了这一行为,严格遵循C++标准的要求,禁止此类不符合规范的用法。

修复思路(参考)

由于Booth类模板已经通过N参数明确了数组的大小,直接使用模板参数N代替data.size()即可:

std::bitset<N> bit_set{};

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 23:01:04