【问题标题】:How to specify a custom class conforms to a standard or custom type trait如何指定自定义类符合标准或自定义类型特征
【发布时间】:2021-02-10 05:03:02
【问题描述】:

我觉得我错过了什么。我看不到任何关于我应该如何指定我的班级具有特征的信息。 例如

#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 索引的对象指向存储组件的已知数组,并且在复制原始对象时也必须复制该数组对象。因此,尽管该类由所有可平凡复制的基元组成,但它不会是可平凡复制的。
  3. 具有唯一 ID 的对象,即使在复制时也必须更新,使其不可轻易复制。
  4. 一种复杂的容器类型,它在数据之前存储控制块,使其易于复制,但也可以选择非平凡复制以清理碎片内存。

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

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

提前致谢。

【问题讨论】:

    标签: c++ typetraits


    【解决方案1】:

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

    一个类满足is_trivially_copyable如果它没有用户定义的复制构造函数,并且它的非静态数据成员也没有一个,递归。用户定义的类都不满足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>);
    

    【讨论】:

    • 所以你的意思是写integral = false; 会使类就类型特征而言是非整数的?
    • 不,我不是这么说的。我的意思是您需要删除以 trait 开头的 2 行,标准库会自行决定您的类是非完整的且可轻松复制。
    • 那么有没有办法手动指定traits?
    • 不,您不能手动指定特征。这不是本意。
    【解决方案2】:

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

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

    2-4:您要么删除复制构造函数并使类不可复制,要么使用所需的自定义逻辑定义复制构造函数,这本身就使类不可复制。

    【讨论】:

      猜你喜欢
      • 2014-10-07
      • 1970-01-01
      • 1970-01-01
      • 2021-01-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-17
      相关资源
      最近更新 更多