【问题标题】:Static assert the size of a template type on instantiation在实例化时静态断言模板类型的大小
【发布时间】:2016-07-17 08:51:24
【问题描述】:

我想在用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&lt;T&gt; 在其类定义中仍然是一个不完整的类型,因此不能将上述static_assert 放入类定义中

  • static_assertsizeof 不会在所有编译器(如 Clang)中的未实例化函数内部进行评估,因此不能将其放入虚拟成员函数中

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

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

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

我决定取消删除此问题,并将其保留为将来可能的解决方案。

【问题讨论】:

  • 当然sizeof 不允许用于不完整的类型,但是当您实例化结构时,T 的类型不能不完整,否则无论有没有@,它都无法编译987654337@
  • 你不能在不知道类型大小的情况下创建联合,所以无论如何你都需要类型是完整的。所以,第一个解决方案应该没问题。
  • 仍然有析构函数,但是(至于构造函数)你可能会破坏一些属性(聚合,容易破坏)。你必须启用移动/复制构造函数/赋值。
  • @OMGtechy 不,类 A 在其类定义中仍然不完整,因此第一个解决方案无法编译。
  • @SomeWittyUsername 是的,但没有人谈论 T 是不完整的。 A 在其类定义中。

标签: c++ templates static-assert


【解决方案1】:

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

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

【讨论】:

  • 是的,但正如@Jarod42 在他的评论中所说,这将打破聚合规则和微不足道的默认可破坏性。
【解决方案2】:
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>
>;

【讨论】:

    猜你喜欢
    • 2017-06-20
    • 1970-01-01
    • 2013-06-27
    • 2014-11-05
    • 2013-02-11
    • 1970-01-01
    • 2021-03-01
    • 1970-01-01
    • 2011-04-11
    相关资源
    最近更新 更多