如何指定自定义 class 符合标准或自定义类型特征

How to specify a custom class conforms to a standard or custom type trait

我觉得我错过了什么。我看不出我应该如何指定我的 class 有一个特征。 例如

#include <type_traits>
class foo
{
    type_trait trivially_copyable = true; //?
    type_trait integral = false; //?

    public:
        foo(const int& val);
        int get_x() const;
    private:
        int m_x;
};

这在以下情况下很有用:

  1. 围绕 int32_t 的包装器充当 Unicode 字符,使用 int 进行复制优化但不具有整数特征,因此标准函数不会对其进行数学计算。
  2. 一个具有 size_t 索引的对象到一个存储组件的已知数组,并且在复制原始对象时也必须复制数组对象。因此,尽管 class 由所有可平凡复制的基元组成,但它仍将不可平凡复制。
  3. 具有唯一 ID 的对象,即使在复制时也必须更新,使其不易复制。
  4. 一种复杂的容器类型,它在数据之前存储控制块,使其可平凡复制,但也可以选择非平凡复制以清理碎片内存。

有人会解释如何在我自己的 classes 中指定类型特征,那太好了。

作为第 2 条和第 4 条的跟进,如果我实现一个非平凡的复制构造函数,编译器会自动将该函数标记为不可平凡复制(反之亦然),还是我需要每次都手动标记它时间?

提前致谢。

您不能指定标准特征 - 这不是本意。特征 (std::is_trivially_copyable and std::is_integral) 由 标准库本身。

如果 class 没有用户定义的复制构造函数,并且其非静态数据成员的 none 也有一个,则递归地满足 is_trivially_copyable。 None 的用户自定义 class 满足 is_integral.

因此,在您的示例中,class foo(如果您删除以 type_trait 开头的无效语句)自动具有您想要的特征,即它是平凡可复制的和非整数的。

即使您不能明确指定特征,您也可以验证它们是否满足。例如:

#include <type_traits>
class foo
{
    public:
        foo(const int& val);
        int get_x() const;
    private:
        int m_x;
};
static_assert( is_trivially_copyable<foo>::value);

从 C++17 开始,您可以将相同的断言写得更短:

static_assert( is_trivially_copyable_v<foo>);

C++ 类型特征是隐式的。您可以通过满足他们的要求来选择加入或退出。

1: is_integral 仅标识标准整数类型。包装器类型永远不会满足它,即使是用于数学用途也是如此。

2-4:您可以删除复制构造函数并使 class 不可复制,或者使用所需的自定义逻辑定义复制构造函数,这本身会使 class 不可复制.