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

MSVC工具集143中带consteval构造函数成员的指定初始化器编译错误

指定初始化器调用consteval构造函数的编译差异问题

现象复现

以下代码在Clang 18、GCC 14中可正常编译,但在MSVC工具集143下编译失败:

struct ConstEval {
    consteval ConstEval(int x) : a{ x } {}
    int a;
};

struct HasConstEval {
    ConstEval ceval;
};


int main()
{
    HasConstEval x{
        .ceval = 1
    };
}

MSVC报错指向指定初始化器行:

error C7595: 'ConstEval::ConstEval': call to immediate function is not a constant expression

但如果给HasConstEval添加构造函数并直接调用(移除指定初始化器),MSVC则能正常编译。

标准规定分析

根据C++20及后续标准,聚合初始化(包括使用指定初始化器的场景)中,成员的初始化操作只要满足初始化表达式是常量表达式,且consteval构造函数的调用符合常量表达式要求,就允许在编译期完成。

这里.ceval = 1的本质是用常量1初始化ConstEval成员,调用其consteval构造函数——这个调用完全符合常量表达式的要求:输入是编译期常量,构造过程无副作用,没有违反consteval函数的调用限制。因此标准层面这段代码是合法的。

结论:MSVC编译器实现缺陷

这是MSVC的编译器bug,而非C++标准的规定问题:

  • MSVC在处理聚合类型的指定初始化器时,未能正确识别consteval构造函数的调用处于常量表达式上下文,错误地判定该调用不是常量表达式,从而触发C7595错误。
  • 当给HasConstEval添加显式构造函数后,构造函数内部对ConstEval构造函数的调用,MSVC能正确识别为编译期可完成的操作,因此编译通过。

临时解决方案

  1. 给HasConstEval添加显式构造函数:
struct HasConstEval {
    ConstEval ceval;
    constexpr HasConstEval(int val) : ceval{val} {}
};

int main() {
    HasConstEval x{1};
}
  1. 在指定初始化器中显式调用构造函数(绕过MSVC的识别缺陷):
int main() {
    HasConstEval x{
        .ceval = ConstEval{1}
    };
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.01 12:32:27