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

常量求值中dynamic_cast的行为:程序是否合法?输出应为多少?

常量求值场景下构造函数内dynamic_cast的行为问题
#include <iostream>

struct A {
    constexpr A();
    virtual void f() {}
    bool x;
};

struct B : A {};

constexpr A::A() { 
    x = dynamic_cast<B*>(this);
}
constexpr bool b = B{}.x;

int main() {
    std::cout << B{}.x << b;
}

现象说明

  • 普通求值时,main中B{}.x输出0:在基类A的构造函数执行期间,对象的动态类型是A(派生类B的成员尚未构造),此时dynamic_cast<B*>(this)返回nullptr,赋值给bool类型的x后结果为false(即0)。
  • 常量求值时各编译器行为分歧:
    • Clang输出第二个0,符合预期;
    • MSVC输出第二个1,错误判定dynamic_cast返回非空指针;
    • GCC报错,认为constexpr bool b = B{}.x不是合法的常量表达式。

问题解答

程序是否定义良好?

该程序符合C20及后续标准,是定义良好的。C20允许在constexpr构造函数中使用dynamic_cast,只要转换操作在常量求值上下文中的结果是确定的:此处转换必然失败返回nullptr,将nullptr转换为bool得到false,属于合法的常量表达式。

正确输出应为多少?

正确输出是00。无论普通求值还是常量求值,在A的构造函数执行阶段,对象的动态类型始终是A(派生类B的构造尚未完成),因此dynamic_cast<B*>(this)必然返回nullptr,x的值始终为false(即0)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 21:25:18