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

为const非字面量类型启用std::move是否属于未定义行为?

含const字面量类型成员类的移动操作UB判定疑问

const成员字面量类型变量存在一个问题:std::move默认会调用拷贝构造函数而非移动构造函数,这使得包含const字面量类型成员的类的移动赋值仅能在不安全的异常场景下实现。

以下代码看似可以实现对const类型对象内容的实际移动:

#include <string>
#include <iostream>
#include <type_traits>

template<class T>
std::remove_const_t<T>& de_const(T& obj) noexcept {
    return *static_cast<std::remove_cv_t<T>*>(const_cast<void*>(static_cast<const volatile void*>(&obj)));
}

struct A {
    const std::string s;
};

int main()
{
    A a{ "asdfasdasdfasdfasdfasdf" }, b{ "12341234123412341234" };
    std::destroy_at(&a.s);
    std::construct_at(&de_const(a.s), std::move(de_const(b.s)));
    std::cout << "a.s=" << a.s << "\n"; // a.s现在存储原b对象的内容
    std::cout << "b.s=" << b.s << "\n"; // b对象仍处于有效状态,但内部资源已被移走

    /* 预期输出
    a.s=12341234123412341234
    b.s=
    */
}

相关已知规则与疑问:

  • 自C++20起,使用std::construct_at将已析构的const std::string透明替换为新的std::string属于合法操作
  • 原作者猜测:将移动源字符串通过自定义的de_const工具移除const限定后传入移动构造的操作,从C++技术规范层面判断属于未定义行为(UB)
  • 明确的UB场景:如果字面量类型本身是完整const对象,上述修改操作明确为UB;示例中结构体A的s成员不属于该场景

核心问题:上述代码中的实现是否属于未定义行为?

实际测试结果:该代码在MSVC、GCC、Clang编译器下均可成功运行,输出结果与预期一致。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 21:45:38