What is Type Triat?
-
Way to inspect properties & transform properties of template variable. These are resolved at compile time.
Why this is good? We can improve our code, for particular data types eg: pointers.
#include <type_traits>
cout << is_same <int, int32_t>::value; //1 If T and U are same type return true else false.
cout << is_same <int, float>::value; //0
Types of Type Triat?
1. Primary Type Triat
/usr/include/boost/type_traits/is_void.hpp
/usr/include/c++/8/type_traits.cpp
is_void: checks if a type is void
is_null_pointer(C++14): checks if a type is std::nullptr_t
is_integral:checks if a type is an integral type
is_floating_point:checks if a type is a floating-point type
is_array:checks if a type is an array type
is_enum:checks if a type is an enumeration type
is_union:checks if a type is an union type
is_class:checks if a type is a non-union class type
is_function:checks if a type is a function type
is_pointer:checks if a type is a pointer type
is_lvalue_reference: checks if a type is a lvalue reference
is_rvalue_reference: checks if a type is a rvalue reference
is_member_object_pointer: checks if a type is a pointer to a non-static member object
is_member_function_pointer: checks if a type is a pointer to a non-static member function
2. Composite Type Triat
is_fundamental: checks if a type is a fundamental type(void or nullptr_t)
is_arithmetic: checks if a type is an arithmetic type
is_scalar: checks if a type is a scalar type
- cv-qualified arithmetic, pointer, pointer to member, enumeration, or nullptr_t type
is_object: checks if a type is an object type
is_compound: checks if a type is a compound type
- array, function, object pointer, function pointer, member object pointer, member function pointer,
reference, class, union, or enumeration,
is_reference: checks if a type is either a lvalue reference or rvalue reference
is_member_pointer: checks if a type is a pointer to an non-static member function or object
- Example:
int main(){
class test{};
cout << (is_compound <test>::value
? "T is compound"
: "T is not a compound") < '\n';
cout << (is_compound <int>::value
? "T is compound"
: "T is not a compound") << '\n';
}
/*
Output:
# ./a.out
T is compound
T is not a compound
*/
Supported Operation
Tells if type supports the operation or not?
is_constructible,is_trivially_constructible,is_nothrow_constructible: checks if a type has a constructor for specific arguments
is_default_constructible,is_trivially_default_constructible,is_nothrow_default_constructible:checks if a type has a default constructor
is_copy_constructible,is_trivially_copy_constructible,is_nothrow_copy_constructible:checks if a type has a copy constructor
is_move_constructible,is_trivially_move_constructible,is_nothrow_move_constructible:checks if a type can be constructed from an rvalue reference
is_assignable,is_trivially_assignable,is_nothrow_assignable:checks if a type has a assignment operator for a specific argument
is_copy_assignable,is_trivially_copy_assignable,is_nothrow_copy_assignable:checks if a type has a copy assignment operator
is_move_assignable,is_trivially_move_assignable,is_nothrow_move_assignable:checks if a type has a move assignment operator
is_destructible,is_trivially_destructible,is_nothrow_destructible:checks if a type has a non-deleted destructor
has_virtual_destructor:checks if a type has a virtual destructor
is_swappable_with,is_swappable,is_nothrow_swappable_with,is_nothrow_swappable:checks if objects of a type can be swapped with objects of same or different type
- Example (is_copy_constructible)
T is copy_constructible type if: 1. T is not a referenceable type OR 2. a function type with a cv-qualifier-seq
#include <type_traits>
struct Ex1 {
string str; // member has a non-trivial copy ctor
};
int main(){
if(is_copy_constructible::value)
cout << "Ex1 is copy-constructible";
}
/*./a.out
Ex1 is copy-constructible
*/
Miscellaneous transformations
- List of all miscellaneous type traits
1. enable_if: Helps in conditionally removing functions from overload resolution in SFINAE based on type traits &
provide separate function overloads and specializations for different type traits.
#include <iostream>
#include <type_traits>
using namespace std;
// 1st argument is_integral::value 2nd: int. Hence type deduced as int
template <typename T, enable_if_t <is_integral <T>::value, int> = 0>
void fun(T a,T b){
cout << a+b;
}
int main(){
fun('a','b'); //195
// fun(10.5,9.5); //error: no matching function for call to ‘fun(double, double)’
fun(1,2); //3
}