I'm currently writing a C++ memory editing library and for the read/write APIs I use type traits (std::is_pod, std::is_same) and boost::enable_if to provide 3 overloads:
Overloads 2 and 3 are simply 'wrappers' around overload 1. (So if you're reading a std::vector or std::basic_string and T is not POD it will fail, as it should.)
Recently I wanted to use std::array for a bunch of reads and writes because I knew the size of the data I wanted to read and write at compile time (I was writing a wrapper around the PE file format).
I wrote the code to use std::array, and then intended to add another overload for detection and handling of std::array types, but I accidentally hit compile and to my surprise it worked!
I'm currently using MSVC 10 and it turns out that for std::array if T is POD then std::array is POD. (Which means I can just use overload 1 and it works.)
My question is whether this is guaranteed by the C++ standard or left up to the implementation.
I know I could check the standard myself, but I don't trust myself as much as I trust some of the language lawyers on this site, so I figured it would be best to get a 'second opinion'. ;)
Thanks
P.S. Code available here (it's a header-only lib): http://code.google.com/p/hadesmem/source/browse/trunk/HadesMem-v2/Hades-Memory/Hades-Memory/MemoryMgr.h#86
In modern C++, we strongly recommend using std::vector or std::array instead of C-style arrays described in this section. Both of these standard library types store their elements as a contiguous block of memory.
A POD (plain old data) object has one of these data types--a fundamental type, pointer, union, struct, array, or class--with no constructor. Conversely, a non-POD object is one for which a constructor exists.
std::pair<T,U> isn't a class aggregate, since it has a user-defined constructor, and that means it also isn't a POD.
§23.3.1:
An array is an aggregate (8.5.1) that can be initialized with the syntax
array a<T, N> = { initializer-list };
where initializer-list is a comma separated list of up to N elements whose types are convertible to T.
In C++03, POD was defined in terms of aggregate: a class where every subobject is native or an aggregate is POD. So, by backwards compatibility, a C++0x std::array
is POD.
Or, to be anal, one can compare the bullet-points of §9/5 (defining trivial class) 9/6 (defining standard-layout) and 9/9 (combining preceding requirements into POD) with those of 8.5.1/1, which defines aggregates.
8.5.1:
An aggregate is an array or a class (Clause 9) with no user-provided constructors (12.1), no brace-or-equal- initializers for non-static data members (9.2), no private or protected non-static data members (Clause 11), no base classes (Clause 10), and no virtual functions (10.3).
Indeed the requirements in Clause 9 cover array
as long as its element type is also POD and the implementation does not declare operator=
or move
inside array
in addition to the specifications.
To be really anal, 17.5.2.2 says
- For the sake of exposition, Clauses 18 through 30 and Annex D do not describe copy/move constructors, assignment operators, or (non-virtual) destructors with the same apparent semantics as those that can be generated by default (12.1, 12.4, 12.8).
- It is unspecified whether the implementation provides explicit definitions for such member function signa- tures, or for virtual destructors that can be generated by default.
The note in the pseudo-code for template class array
is
// No explicit construct/copy/destroy for aggregate type
Does construct/copy/destroy
include operator=
(assignment) or move
? It probably should, but I don't think, by the strictest reading, it does.
Note that this "affects" not only POD-ness, but also trivial copyability as Johannes mentions.
By definition of POD:
9 Classes
9 A POD struct is a class that is both a trivial class and a standard-layout class, and has no non-static data members of type non-POD struct, non-POD union (or array of such types). Similarly, a POD union is a union that is both a trivial class and a standard layout class, and has no non-static data members of type non-POD struct, non-POD union (or array of such types). A POD class is a class that is either a POD struct or a POD union.
[Emphasis mine]
std::array
does satisfy all the requirements of being a trivial, standard-layout class template. So the answer to your question is yes.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With