If the class definition does not explicitly declare a copy constructor
and there is no user-declared move constructor, a copy constructor is
implicitly declared as defaulted (8.4).
If my understanding of the rules is correct, the class X in the
example below has no copy constructors, and its default and move
constructors are supposed to be trivial.
struct X
{
X() = default;
X(X&&) = default;
int i;
};
According to 9/5,
"A trivially copyable class is a class that:
- has no non-trivial copy constructors (12.8),
- has no non-trivial move constructors (12.8),
- has no non-trivial copy assignment operators (13.5.3, 12.8),
- has no non-trivial move assignment operators (13.5.3, 12.8), and
- has a trivial destructor (12.4)."
Should the class X be considered as trivially copyable?
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Yes. The basic idea of triviality is related to the question whether
it is OK to bit-copy (memcpy, memmove) an object of that type, not
whether a normal copy expression would be well-formed or not.
Note that a similar discussion would apply to the example given in
http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1140
The type A is intended to be trivially copyable even though the
following program is ill-formed:
struct A { const int i; };
int main() {
A a = {0}, b = {1};
a = b; // Error
}
because the copy-assignment operator is also deleted (12.8/25). To make
this work the standard will need further adaption, because 12.8/27
"A copy/move assignment operator for class X is trivial if it is neither
user-provided nor deleted [..]"
currently contradicts this position.
Note that the recent core-near library-proposal
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3142.html
is intended to follow the same spirit: The trait
std::is_trivially_constructible is designed to return true, if the
following two conditions apply:
1) The corresponding initialization would be well-formed, i.e.
std::is_constructible<>::value evaluates to true.
2) There are no non-trivial functions involved.
This is a typical query in code, when you are asking for a type
where you want to check whether you could *optimize* an otherwise
valid copy-construction by a memcpy.
For situations where you are *only* interested in triviality you
are typically involved in hardware-near programming. Here you would
better use the traits std::is_trivial or std::is_trivially_copyable
and you can ignore the "expression-related" aspects of the copy.
HTH & Greetings from Bremen,
Daniel Krügler