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

创建不可构造对象:std::bit_cast是否应限制为隐式生存期类型?

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

我们可以设计不可构造类,但借助std::bit_cast仅要求输入输出为trivially copyable类型的特性,能够成功实例化这类对象。

问题背景与测试代码

我试图理解为何无公开构造函数的类无法完全阻止独立对象创建,同时验证trivially copyable不意味着隐式生存期。Jarod42提示了一个仅含赋值运算符、无构造函数的类,测试代码如下:

#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执行失败,推测是未执行拷贝省略,需要不可用的移动构造函数)

隐式生存期类型的判定

Test并非隐式生存期类型,依据C++标准:

  • 存在用户声明的构造函数,因此不是聚合类型;
  • 无符合条件的平凡构造函数(均已删除)。

而std::start_lifetime_as要求输出为隐式生存期类型(甚至要求是聚合类型,似乎过于严格),因此我认为std::bit_cast应限制输出类型为隐式生存期类型,输入类型的限制则有待商榷。

实际应用场景

此问题并非纯理论,不可构造类可作为仅用于继承的基实现类,示例如下:

// 不可构造、非隐式生存期类型
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;};
};

补充思考:访问说明符的影响

特殊成员函数的访问说明符不属于trivially copyable或隐式生存期类型的定义,因此如下类同时满足这两个特性,让合理的要求制定更复杂:

class Test {
    int val;
    Test() = default;
    Test(Test const&) = default;
    Test(Test&&) = default;
    Test& operator=(Test const&) = default;
    Test& operator=(Test&&) = default;
    ~Test() = default;
};

我的分析是否存在错误?


内容的提问来源于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 20:54:51