【问题标题】:Type trait for trivial types普通类型的类型特征
【发布时间】:2015-03-30 20:50:44
【问题描述】:

我希望有一个类型特征,对于任何在使用前不需要初始化内存并且可以将其复制构造函数实现为 memcpy 的类型返回 true。

我希望它返回 true

  • 整数类型(char、short int、int、long int 等)
  • 浮点数类型(float、double)
  • il::array(il::array 是我自己的 std::array 实现)因为 T 是 int、double、il::array 等之一。

对于诸如 std::vector 之类的东西以及在构造时需要某些东西的任何对象(大多数对象)为 false。

std::is_pod 似乎非常接近我想要的,因为它也为 std::array 返回 true,但不幸的是它不会为我自己的 il::array 返回 true。有什么方法可以“教导” is_pod 我的 il::array 表现为普通的旧数据,或者一种简单的方法来推出我自己的类型特征?

有关信息,这是我对 il::array: 的实现:

namespace il {

template <typename T, int n>
class array {
private:
    T data_[n > 0 ? n : 1];
public:
    array(const T& value)
            : array() {
        for (int k = 0; k < n; ++k) {
            data_[k] = value;
        }
    }
    array(std::initializer_list<T> list) {
        IL_ASSERT(n == static_cast<int>(list.size()));
        for (int k = 0; k < n; ++k) {
            data_[k] = *(list.begin() + k);
        }
    }
    const T& operator[](int k) const {
        IL_ASSERT(static_cast<unsigned int>(k) < static_cast<unsigned int>(n));
        return data_[k];
    }
    T& operator[](int k) {
        IL_ASSERT(static_cast<unsigned int>(k) < static_cast<unsigned int>(n));
        return data_[k];
    }
    T* data() {
        return data_;
    }
    int size() const {
        return n;
    }
};

}

【问题讨论】:

    标签: c++ typetraits


    【解决方案1】:

    我希望有一个类型特征,对于任何在使用前不需要初始化内存并且可以将其复制构造函数实现为 memcpy 的类型返回 true。

    您正在描述一个普通类型。您可以通过std::is_trivial 进行检查。

    std::is_pod 似乎和我想要的很接近

    这还要求该类型具有标准布局,这限制了其数据成员的声明方式和位置。

    不幸的是,我自己的 il::array 没有返回 true

    也许这不是标准布局,在这种情况下is_trivial 应该适合你。或者在任何情况下它实际上都不是微不足道的;在这种情况下,您可能需要修复它。

    更新:它有一个用户声明的默认构造函数,这使它变得不平凡。由于它只检查编译时常量的值,因此您可以将其替换为static_assert;或将n 更改为更合理的无符号类型,例如std::size_t,以消除对完整性检查的需要。

    但您仍然需要将其声明为默认值

    array() = default;
    

    否则其他构造函数的存在会删除它。

    有什么方法可以“教导”is_pod 我的 il::array 表现为普通的旧数据?

    您可以编写自己的特质,并针对您的类型进行专业化。但这会很奇怪。如果你的类型应该是琐碎的或 POD,那就这样吧。

    【讨论】:

    • 原来 std::is_trivial<:array>>::value 是假的,我希望它是真的。顺便说一句 std::is_trivial<:array>>::value 是真的。我的 il::array 和 std::array 几乎一样。
    • @InsideLoop:在这种情况下,你已经做了一些事情让它变得不平凡;要么声明一个默认、复制或移动构造函数,要么给它一个重要的数据成员或基类。
    • 迈克。我已经发布了 il::array 的实现。我不明白是什么让 il::array.
    • @InsideLoop:现在您已经发布了代码,我们可以看到有一个重要的默认构造函数。您需要删除它以使其变得微不足道。如果您想保持完整性检查,可以将其替换为 static_assert。或者将n 设为无符号可能更明智。
    • 删除默认构造函数没有任何区别(我已经编辑了帖子以删除它)。关于 unsigned int,我想远离它们,因为将它们用作 STL 中的索引是错误的(Bjarne Stroustrup、Scott Meyer、Herb Sutter 等都承认)。这是我实现自己的 std::vector 和 std::array 的众多原因之一。
    猜你喜欢
    • 1970-01-01
    • 2014-06-10
    • 1970-01-01
    • 2016-07-31
    • 1970-01-01
    • 2021-09-14
    • 2013-06-28
    • 2010-12-03
    • 1970-01-01
    相关资源
    最近更新 更多