std::is_assignable, std::is_trivially_assignable, std::is_nothrow_assignable
Min standard notice:
Header: <type_traits>
- If the expression std::declval
() = std::declval() is well-formed in unevaluated context, provides the member constant value equal to true. Otherwise, value is false. Access checks are performed as if from a context unrelated to either type.
# Declarations
template< class T, class U >
struct is_assignable;
(since C++11)
template< class T, class U >
struct is_trivially_assignable;
(since C++11)
template< class T, class U >
struct is_nothrow_assignable;
(since C++11)
# Notes
This trait does not check anything outside the immediate context of the assignment expression: if the use of T or U would trigger template specializations, generation of implicitly-defined special member functions etc, and those have errors, the actual assignment may not compile even if std::is_assignable<T,U>::value compiles and evaluates to true.
# Example
#include <iostream>
#include <string>
#include <type_traits>
struct Ex1 { int n; };
int main()
{
std::cout << std::boolalpha
<< "int is assignable from int? "
<< std::is_assignable<int, int>::value << '\n' // 1 = 1; wouldn't compile
<< "int& is assignable from int? "
<< std::is_assignable<int&, int>::value << '\n' // int a; a = 1; works
<< "int is assignable from double? "
<< std::is_assignable<int, double>::value << '\n'
<< "int& is nothrow assignable from double? "
<< std::is_nothrow_assignable<int&, double>::value << '\n'
<< "string is assignable from double? "
<< std::is_assignable<std::string, double>::value << '\n'
<< "Ex1& is trivially assignable from const Ex1&? "
<< std::is_trivially_assignable<Ex1&, const Ex1&>::value << '\n';
}