【问题标题】:How to make a type T that `std::is_empty_v<T> && sizeof(T) > 1` is true?如何使类型 T `std::is_empty_v<T> && sizeof(T) > 1` 为真?
【发布时间】:2022-01-08 02:50:59
【问题描述】:

我在here 遇到了一个有趣的测验问题:

编写一个包含类类型 T 的翻译单元,使得 std::is_empty_v&lt;T&gt; 为真,但 sizeof(T) 大于 1。

我考虑了一段时间,但没有解决方案。

如何使T 的类型std::is_empty_v&lt;T&gt; &amp;&amp; sizeof(T) &gt; 1 为真?

【问题讨论】:

  • 你能把std::is_empty&lt;T&gt; 专门用于你的类型吗?那是一种撒谎方式。
  • 类 S { char c[2]; };模板 struct std::is_empty : std::true_type { };你没有说它应该是有效的 C++ :P
  • @TanveerBadar 那是未定义的。
  • @Mestkon 通过这种推理,每一个“我怎么能[某事]?”问题可以通过“试试 UB,也许它对你有用?”来回答。
  • @FrançoisAndrieux 从技术上讲,他们都可以:P。但是,它仍然是一个测验,测验并不总是在寻找正确的答案。它们可以包括技巧问题和类似的东西

标签: c++ c++11 types template-meta-programming typetraits


【解决方案1】:

std::is_empty 检查是否没有成员。您可以使用对齐来强制大小大于 1:

struct alignas(2) T {};

static_assert(std::is_empty_v<T>);
static_assert(sizeof(T) > 1);

【讨论】:

    【解决方案2】:

    由于两个相同的空类不能共享同一个地址,我们可以创建一个类,继承一个空基,同时也有一个空基作为成员来禁止EBO,使其大小大于1

    #include<type_traits>
    
    struct B { };
    struct D : B { [[no_unique_address]] B b; };
    
    static_assert(std::is_empty_v<D> && sizeof(D) > 1);
    

    Demo.

    【讨论】:

    • 如果您添加解释为什么使用继承,以及 [[no_unique_address]] 以及如何解决问题,答案将会得到改善。
    猜你喜欢
    • 2015-04-24
    • 2016-12-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-25
    • 2012-08-01
    • 2018-03-09
    相关资源
    最近更新 更多