如何修改代码使用gsl::at,避免触发C1001内部编译错误
问题原因
你遇到的C1001内部编译错误是MSVC编译器的已知缺陷,触发原因是std::vector<bool>是STL中的特殊代理容器,其下标操作返回的不是原生bool类型,而是std::_Bit_reference代理对象,旧版本MSVC对该代理对象和gsl::at的模板推导组合处理异常,进而触发了编译器内部崩溃,你的代码逻辑本身没有错误。
正确修复方案
以下几种方案都可以消除C26446警告,同时规避编译错误:
- 使用
std::vector自带的边界检查at()方法(最简洁)std::vector原生提供带边界检查的at()成员函数,完全满足bounds.4规范的要求,也可以避免gsl::at和vector<bool>的兼容问题:
if (pListWeeksToPrint != nullptr && !pListWeeksToPrint->at(iDate)) continue;
- 显式转换
gsl::at的返回值类型
如果必须使用gsl::at,可以显式将代理对象转换为原生bool,绕开编译器的模板推导bug:
if (pListWeeksToPrint != nullptr && !static_cast<bool>(gsl::at(*pListWeeksToPrint, iDate))) continue;
- 拆分取值逻辑到单独语句
如果上述方案仍然报错,可以把取值操作从if条件中拆分出来,避免编译器解析复杂表达式时触发异常:
if (pListWeeksToPrint != nullptr) { bool isNeedPrint = gsl::at(*pListWeeksToPrint, iDate); if (!isNeedPrint) continue; }
内容的提问来源于stack exchange,提问作者Andrew Truckle
相关产品推荐
相关产品推荐

