std::is_copy_assignable, std::is_trivially_copy_assignable, std::is_nothrow_copy_assignable

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_assignable;

(since C++11)

template< class T >
struct is_trivially_copy_assignable;

(since C++11)

template< class T >
struct is_nothrow_copy_assignable;

(since C++11)

# Notes

The trait std::is_copy_assignable is less strict than CopyAssignable because it does not check the type of the result of the assignment (which, for a CopyAssignable type, must be an lvalue of type T) and does not check the semantic requirement that the argument expression remains unchanged. It also does not check that T satisfies MoveAssignable, which is required of all CopyAssignable types.

# Example

#include <iostream>
#include <type_traits>
#include <utility>
 
struct Foo { int n; };
 
int main()
{
    std::cout << std::boolalpha
              << "Foo is trivially copy-assignable? "
              << std::is_trivially_copy_assignable<Foo>::value << '\n'
              << "int[2] is copy-assignable? "
              << std::is_copy_assignable<int[2]>::value << '\n'
              << "int is nothrow copy-assignable? "
              << std::is_nothrow_copy_assignable<int>::value << '\n';
}

# 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