实例化时静态断言模板类型的大小

Static assert the size of a template type on instantiation

本文关键字:类型 静态 断言 实例化      更新时间:2023-10-16

我想在用static_assert实例化时检查以下结构的大小,以约束未命名的struct是紧密封装的,因此A的大小等于sizeof(T) * 3

template <typename T>
struct A
{
   union
   {
      struct { T a, b, c; };
      T arr[3];
   };
};

这可以通过完成

static_assert(sizeof(A<T>) == sizeof(T) * 3, "hey something went wrong");

但是

  • 由于A<T>在其类定义中仍然是一个不完整的类型,将上述static_assert放入类定义中不是一个选项

  • 带有sizeofstatic_assert不会在所有编译器(如Clang)中的未实例化函数内部求值,因此将其放入伪成员函数不是的选项

  • static_assert放在构造函数或析构函数中是一个解决方案,但在上面的例子中,不存在用户定义的构造函数(想想聚合),进一步想象多个构造函数的情况,在这种情况下,我将避免在所有构造函数中执行断言

  • 从另一个结构继承A,并在A的定义中对其执行static_assert将是一个解决方案,但我希望保持结构简单,而不会干扰辅助结构

我还缺少其他解决方案吗?

我决定取消删除这个问题,并保留它以备将来可能的解决方案

一个特殊的成员函数(几乎)可以保证实例化,它是析构函数:

~A() noexcept { static_assert(sizeof(A<T>) == sizeof(T) * 3, "hey something went wrong"); }
namespace my_private_impl{
    struct impl_tag{};
    template <typename T,typename tag>
    struct A_impl{
        static_assert(is_same<tag,impl_tag>{}(),"you evil cheater");
        union{
            struct { T a, b, c; };
            T arr[3];
        };
    };
};
template<typename T>
using A=std::enable_if_t<
    sizeof(my_private_impl::A_impl<T,my_private_impl::impl_tag>) == sizeof(T) * 3,
    my_private_impl::A_impl<T,my_private_impl::impl_tag>
>;