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

如何让模板类嵌套类B根据T是否为void决定成员数量

实现模板类A的嵌套类B的条件成员存储

需求明确:

  • 当模板类A的参数T为void时,嵌套类B仅包含size_t sz成员,且sizeof(B)严格等于sizeof(size_t)
  • 当T不为void时,B同时包含size_t sz和T类型的成员

已尝试方案的局限

  1. 位域方案:仅支持整数类型,且无法直接命名T类型成员(命名位域宽度为0会触发编译错误),访问数据不便
static constexpr bool is_void = std::is_same_v<void, T>;
using type = std::conditional_t<is_void, bool, T>;

struct B {
  size_t sz;
  type : (is_void ? 0 : sizeof(type));
  // 命名位域宽度为0会编译失败,无名称则无法正常访问T成员
};
  1. 条件继承方案:依赖空基类优化(EBO),虽然可行,但希望用更原生简洁的语法实现
struct empty_class {};
struct container { T t; };

static constexpr bool is_void = std::is_same_v<void, T>;
using base = std::conditional_t<is_void, empty_class, container>;

struct B : base {
  size_t sz;
};
  1. 特化A<void>:会导致大量代码冗余,不符合代码复用原则

实现类似std::span内部存储的方案

参考std::span中std::__detail::__extent_storage的实现思路,我们可以利用带[[no_unique_address]]属性的条件成员,结合std::conditional和空类型来实现零开销的条件存储:

#include <type_traits>

template<typename T>
class A {
private:
    // 空类型,用于T为void时占位
    struct empty_storage {};
    // 非void时的存储容器
    struct value_storage { T value; };

    using storage_type = std::conditional_t<std::is_same_v<T, void>, empty_storage, value_storage>;

public:
    struct B {
        size_t sz;
        [[no_unique_address]] storage_type storage;

        // 提供统一的访问接口
        template<typename U = T>
        std::enable_if_t<!std::is_same_v<U, void>, T&> get_value() {
            return static_cast<value_storage&>(storage).value;
        }

        template<typename U = T>
        std::enable_if_t<!std::is_same_v<U, void>, const T&> get_value() const {
            return static_cast<const value_storage&>(storage).value;
        }
    };
};

方案说明:

  • 当T为void时,storage_type是empty_storage,结合[[no_unique_address]]属性,空类型不会占用额外内存,此时sizeof(B)等于sizeof(size_t),满足要求
  • 当T不为void时,storage_type是value_storage,包含T类型成员,可通过get_value()接口安全访问
  • 无需继承,直接利用类成员的条件类型和[[no_unique_address]]实现零开销优化,语法更原生简洁

验证:

static_assert(sizeof(A<void>::B) == sizeof(size_t));
static_assert(sizeof(A<int>::B) == sizeof(size_t) + sizeof(int));

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.23 21:05:54