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

实例化不可构造对象:trivially copyable定义是否存在问题?

关于不可构造类被std::bit_cast实例化的问题分析

我们可以设计一个不可构造的类,但我却成功实例化了它的对象:

#include <bit>
#include <cstring>
#include <iostream>

// 不可构造
// 无隐式生命周期
struct Test {
    int val{1};
    Test() = delete;
    Test(Test const&) = delete;
    Test(Test&&) = delete;
    Test& operator=(Test const&) = default;
    Test& operator=(Test&&) = default;
    ~Test() = default;
};

int main() {
    char storage[sizeof(Test)];
    int i{666};
    std::memcpy(storage,&i,sizeof(Test));

    auto HeWhoMustNotBeNamed = std::bit_cast<Test>(storage);
    
    std::cout << HeWhoMustNotBeNamed.val;
}

所有测试编译器(GCC、Clang、MSVC)均将Test识别为**平凡可拷贝(trivially copyable)**类型。

Test和storage满足std::bit_cast的前置条件,因此Clang和MSVC可无未定义行为地创建该不可构造类的对象。

仅GCC编译失败,它尝试调用已删除的移动构造函数返回结果,推测MSVC和Clang对std::bit_cast做了拷贝消除优化,而GCC未做。

我认为该行为违反类的语义,问题出在平凡可拷贝类型的定义上——它允许存在无法拥有实例的类(尽管从逻辑上讲,所有无法存在的对象都可被平凡拷贝)。

我的分析是否有误?注:另有替代方案已作为新问题提出。


补充:该问题并非纯理论,不可构造类可作为仅用于继承的基础实现类:

// 不可构造
// 无隐式生命周期
struct BaseImpl {
    int val{1};
    BaseImpl() = delete;
    BaseImpl(BaseImpl const&) = delete;
    BaseImpl(BaseImpl&&) = delete;
    BaseImpl& operator=(BaseImpl const&) = default;
    BaseImpl& operator=(BaseImpl&&) = default;
    ~BaseImpl() = default;

   protected:
    BaseImpl(int i) : val{i} {};
};

struct Concrete: private BaseImpl
{
    Concrete(int i) : BaseImpl{i}{};
    int Value() const {return BaseImpl::val;};
};

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.01 17:33:08