为何MSVC判定virtual constexpr函数调用运算符调用不构成常量表达式?
MSVC对C++20 constexpr虚函数的编译BUG分析与解决建议
问题本质
你遇到的确实是MSVC的编译器BUG。这段代码完全符合C++20标准:
- C++20允许将
virtual函数声明为constexpr,只要函数本身满足constexpr函数的所有要求 - 你的代码中,
Container对象是constexpr类型,调用operator()时编译器可以通过静态类型确定具体调用的子类实现,不需要运行时虚表查找,完全可以在编译期求值
GCC 10.3+、Clang 12+都能正确编译验证这一点,但MSVC 19.33对这种constexpr虚函数的编译期处理存在缺陷,仅当函数带有virtual修饰时触发错误。
临时解决方案
方案1:移除virtual(无需多态场景)
如果你的代码不需要运行时多态能力,直接删除基类中operator()的virtual关键字,MSVC即可正常编译,代码功能不受影响。
方案2:绕过虚函数调用(保留多态结构)
若需要保留基类的抽象接口,可以手动指定调用子类的成员函数,绕过虚函数机制:
int main () { constexpr Container<int, 3> C = {2, -91, 7}; // 直接调用子类的operator(),避免虚函数查找 constexpr int F = C.Container::operator()(1); static_assert(F == -91); }
方案3:升级MSVC版本
后续发布的MSVC版本(如19.35+)大概率修复了这个constexpr虚函数的处理问题,升级编译器版本是彻底解决的最优方案。
内容的提问来源于stack exchange,提问作者saxbophone
相关产品推荐
相关产品推荐

