std::is_copy_constructible, std::is_trivially_copy_constructible, std::is_nothrow_copy_constructible

Header: <type_traits>

If T is not a complete type, (possibly cv-qualified) void, or an array of unknown bound, the behavior is undefined.

# Declarations

template< class T >
struct is_copy_constructible;

(since C++11)

template< class T >
struct is_trivially_copy_constructible;

(since C++11)

template< class T >
struct is_nothrow_copy_constructible;

(since C++11)

# Notes

In many implementations, is_nothrow_copy_constructible also checks if the destructor throws because it is effectively noexcept(T(arg)). Same applies to is_trivially_copy_constructible, which, in these implementations, also requires that the destructor is trivial: GCC bug 51452, LWG issue 2116.

# Example

#include <string>
#include <type_traits>
 
struct S1
{
    std::string str; // member has a non-trivial copy constructor
};
static_assert(std::is_copy_constructible_v<S1>);
static_assert(!std::is_trivially_copy_constructible_v<S1>);
 
struct S2
{
    int n;
    S2(const S2&) = default; // trivial and non-throwing
};
static_assert(std::is_trivially_copy_constructible_v<S2>);
static_assert(std::is_nothrow_copy_constructible_v<S2>);
 
struct S3
{
    S3(const S3&) = delete; // explicitly deleted
};
static_assert(!std::is_copy_constructible_v<S3>);
 
struct S4
{
    S4(S4&) {}; // cannot bind const, hence not a copy-constructible
};
static_assert(!std::is_copy_constructible_v<S4>);
 
int main() {}

# Defect reports

DRApplied toBehavior as publishedCorrect behavior
LWG 2196C++11the behavior was unclear if const T& cannot be formedthe value produced is false in this case

# See also