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
相关产品推荐
相关产品推荐

