Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does being trivially copyable imply being nothrow copyable?

Tags:

c++

c++17

Alternatively, is there an example of a type with a copy constructor that can throw, but is nontheless trivial? And if not, does that imply that the is_nothrow_copy_constructible_v<T> should be true whenever is_trivially_copy_constructible_v<T> is true?

Note that according to the standard (latest draft [23.15.4.3]), for a type T to be nothrow copyable, we need the expression T t(declval<const T&>()); to be a well-formed variable definition that is known not to throw any exceptions. This wording seems to be somewhat vauge to me - what does it mean for something to be known? Should the noexcept specifier be sufficient to establish that knowledge? or maybe the determination is left to the implementation?


Edit: I realize there's a difference between being trivially copyable, and being trivially copy constructible. My focus is on the latter.

like image 703
SomeStrangeUser Avatar asked Dec 08 '17 21:12

SomeStrangeUser


People also ask

What does trivially copyable mean?

A trivially copyable class is a class that: has no non-trivial copy constructors, has no non-trivial move constructors, has no non-trivial copy assignment operators, has no non-trivial move assignment operators, and has a trivial destructor.

Is STD function trivially copyable?

A std::function might allocate memory for captured variables. As with any other class which allocates memory, it's not trivially copyable.

Is array trivially copyable?

Trivially copyable types have no non-trivial copy operations, move operations, or destructors. Generally, a copy operation is considered trivial if it can be implemented as a bitwise copy. Both built-in types and arrays of trivially copyable types are trivially copyable.

Why is STD pair not trivially copyable?

std::pair has a non-trivial copy-assignment and move-assignment operator. This prevents it from being trivially copyable. Since C++17, if one of the two contained types is not assignable, then the copy/move assignment operator is defined as deleted, which lifts this restriction on being trivially copyable.


2 Answers

Does being trivially copyable imply being nothrow copyable?

No. For example:

struct X {
    X(X&& ) = default;
    X(X const& ) = delete;
};

This type is trivially copyable, but not nothrow copyable... or even copyable at all.


However, given that a type is copyableand trivially copyable, then it must be copyable without throwing (any potential exception would have to come from a non-trivial copy, which can't exist).

Simply defaulting a copy constructor but marking it noexcept(false) defines it as deleted, so such a type would not be copyable.

like image 149
Barry Avatar answered Sep 24 '22 03:09

Barry


On a compiler that implements DR2171:

struct X {
    X(X&) = default;
    template<class U> X(U&&){ throw 1; }
};

static_assert(std::is_trivially_copyable_v<X>, "");
static_assert(std::is_copy_constructible_v<X>, "");
static_assert(!std::is_nothrow_copy_constructible_v<X>, "");
static_assert(!std::is_trivially_copy_constructible_v<X>, "");
like image 41
T.C. Avatar answered Sep 21 '22 03:09

T.C.