Reputation: 6255
I would like to have a type trait that returns true for any type which does not need memory to be initialised before being used and whose copy constructor can be implemented as a memcpy.
I want it to return true for
and false for thing such as std::vector, and any object that needs something at construction (most objects).
std::is_pod seems to be quite close to what I want as it also returns true for std::array, but unfortunately it does not return true for my own il::array. Is there any way to "teach" is_pod that my il::array behaves as plain old data, or an easy way to roll out my own type trait?
For information, here is my implementation of 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;
}
};
}
Upvotes: 1
Views: 337
Reputation: 254431
I would like to have a type trait that returns true for any type which does not need memory to be initialised before being used and whose copy constructor can be implemented as a
memcpy
.
You're describing a trivial type. You can check for that with std::is_trivial
.
std::is_pod
seems to be quite close to what I want
That also requires the type to have standard layout, which places restrictions on how and where its data members are declared.
unfortunately it does not return true for my own
il::array
Perhaps that's not standard layout, in which case is_trivial
should work for you. Or perhaps it's not actually trivial in any case; in which case, you might want to fix it so that it is.
UPDATE: It has a user-declared default constructor, which makes it non-trivial. Since it does nothing but check the value of a compile-time constant, you could replace it with a static_assert
; or change n
to a more sensible unsigned type like std::size_t
to remove the need for the sanity check.
But you'll still need to declare it as defaulted
array() = default;
otherwise the presence of the other constructors will delete it.
Is there any way to "teach"
is_pod
that myil::array
behaves as plain old data?
You could write your own trait, with a specialisation for your type. But that would be weird; if your type is supposed to be trivial or POD, then make it so.
Upvotes: 1