tuple
文件:Test.cpp
#include <iostream>
#include <string>
#include <tuple>
using namespace std;
void test_1()
{
cout << "test_1: ----------------------" << endl;
// create and initialize a tuple explicitly
tuple<int, float, string> t(41, 6.3, "nico");
cout << "tuple<int, float, string>, sizeof = " << sizeof(t) << endl;
// iterator over elements
cout << "t: " << get<0>(t) << " " << get<1>(t) << " " << get<2>(t) << endl;
}
void test_2()
{
cout << endl << "test_2: ----------------------" << endl;
// create tuple with make_tuple()
auto t = make_tuple(22, 44, "stacy");
cout << "t: " << get<0>(t) << " " << get<1>(t) << " " << get<2>(t) << endl;
}
void test_3()
{
cout << endl << "test_3: ----------------------" << endl;
auto t1 = make_tuple(41, 6.3, "nico");
auto t2 = make_tuple(22, 44, "stacy");
// assign second value in t2 to t1
get<1>(t1) = get<1>(t2);
cout << "get<1>(t1) = " << get<1>(t1) << endl;
}
void test_4()
{
cout << endl << "test_4: ----------------------" << endl;
auto t1 = make_tuple(41, 6.3, "nico");
auto t2 = make_tuple(22, 44, "stacy");
// comparsion
if (t1 < t2)
{
cout << "t1 < t2" << endl;
}
else
{
cout << "t2 < t1" << endl;
}
// assigns values for value
t1 = t2;
cout << "t1: " << get<0>(t1) << " " << get<1>(t1) << " " << get<2>(t1) << endl;
cout << "t2: " << get<0>(t2) << " " << get<1>(t2) << " " << get<2>(t2) << endl;
}
void test_5()
{
cout << endl << "test_5: ----------------------" << endl;
tuple<int, float, string> t(77, 1.1, "more light");
int il;
float fl;
string sl;
// 批量赋值
// std::tie会将变量的引用整合成一个tuple,从而实现批量赋值。
tie(il, fl, sl) = t;
cout << "il = " << il << ", fl = " << fl << ", sl = " << sl << endl;
}
void test_6()
{
cout << endl << "test_6: ----------------------" << endl;
typedef tuple<int, float, string> TupleType;
cout << "tuple_size<TupleType>::value = " << tuple_size<TupleType>::value << endl;
tuple_element<1, TupleType>::type fl = 1.1F;
cout << "tuple_element<1, TupleType>::type fl : " << fl << endl;
typedef tuple_element<1, TupleType>::type T;
T fll = 1.1F;
cout << "T fll : " << fll << endl;
}
ostream& operator<< (ostream &out, const tuple<int, float, string>& t)
{
cout << get<0>(t) << " " << get<1>(t) << " " << get<2>(t) << endl;
}
void test_7()
{
cout << endl << "test_7: ----------------------" << endl;
auto t = make_tuple(41, 6.3, "nico");
cout << t;
}
int main()
{
test_1();
test_2();
test_3();
test_4();
test_5();
test_6();
test_7();
return 0;
}
输出:
test_1: ----------------------
tuple<int, float, string>, sizeof = 32
t: 41 6.3 nico
test_2: ----------------------
t: 22 44 stacy
test_3: ----------------------
get<1>(t1) = 44
test_4: ----------------------
t2 < t1
t1: 22 44 stacy
t2: 22 44 stacy
test_5: ----------------------
il = 77, fl = 1.1, sl = more light
test_6: ----------------------
tuple_size<TupleType>::value = 3
tuple_element<1, TupleType>::type fl : 1.1
T fll : 1.1
test_7: ----------------------
41 6.3 nico
type traits
<type_traits>
This header defines a series of classes to obtain type information on compile-time.
The header contains:
- Helper classes: Standard classes to assist in creating compile-time constants.
- Type traits: Classes to obtain characteristics of types in the form of compile-time constant values.
- Type transformations: Classes to obtain new types by applying specific transformations to existing types.
A basic trait for types is the categories in which they can be classified. This is a chart on how these categories overlap:
Helper classes
integral_constant | Integral constant(class template ) |
true_type | True type(class ) |
false_type | False type(class ) |
Type traits
Primary type categories
is_array | Is array(class template ) |
is_class | Is non-union class(class template ) |
is_enum | Is enum(class template ) |
is_floating_point | Is floating point(class template ) |
is_function | Is function(class template ) |
is_integral | Is integral(class template ) |
is_lvalue_reference | Is lvalue reference(class template ) |
is_member_function_pointer | Is member function pointer(class template ) |
is_member_object_pointer | Is member object pointer(class template ) |
is_pointer | Is pointer(class template ) |
is_rvalue_reference | Is rvalue reference(class template ) |
is_union | Is union(class template ) |
is_void | Is void(class template ) |
Composite type categories
is_arithmetic | Is arithmetic type(class template ) | |
is_compound | Is compound type(class template ) | |
is_fundamental | Is fundamental type(class template ) | |
is_member_pointer | Is member pointer type(class template ) | |
is_object | Is object type(class template ) | |
is_reference | Is reference type(class template ) | |
is_scalar | Is scalar type(class template ) |
Type properties
is_abstract | Is abstract class(class template ) | |
is_const | Is const-qualified(class template ) | |
is_empty | Is empty class(class template ) | |
is_literal_type | Is literal type(class template ) | |
is_pod | Is POD type(class template ) | |
is_polymorphic | Is polymorphic(class template ) | |
is_signed | Is signed type(class template ) | |
is_standard_layout | Is standard-layout type(class template ) | |
is_trivial | Is trivial type(class template ) | |
is_trivially_copyable | Is trivially copyable(class template ) | |
is_unsigned | Is unsigned type(class template ) | |
is_volatile | Is volatile-qualified(class template ) |
Type features
has_virtual_destructor | Has virtual destructor(class template ) |
is_assignable | Is assignable(class template ) |
is_constructible | Is constructible(class template ) |
is_copy_assignable | Is copy assignable(class template ) |
is_copy_constructible | Is copy constructible(class template ) |
is_destructible | Is destructible(class template ) |
is_default_constructible | Is default constructible(class template ) |
is_move_assignable | Is move assignable(class template ) |
is_move_constructible | Is move constructible(class template ) |
is_trivially_assignable | Is trivially assignable(class template ) |
is_trivially_constructible | Is trivially constructible(class template ) |
is_trivially_copy_assignable | Is trivially copy assignable(class template ) |
is_trivially_copy_constructible | Is trivially copy constructible(class template ) |
is_trivially_destructible | Is trivially destructible(class template ) |
is_trivially_default_constructible | Is trivially default constructible(class template ) |
is_trivially_move_assignable | Is trivially move assignable(class template ) |
is_trivially_move_constructible | Is trivially move constructible(class template ) |
is_nothrow_assignable | Is assignable throwing no exceptions(class template ) |
is_nothrow_constructible | Is constructible throwing no exceptions(class template ) |
is_nothrow_copy_assignable | Is copy assignable throwing no exceptions(class template ) |
is_nothrow_copy_constructible | Is copy constructible throwing no exceptions(class template ) |
is_nothrow_destructible | Is nothrow destructible(class template ) |
is_nothrow_default_constructible | Is default constructible throwing no exceptions(class template ) |
is_nothrow_move_assignable | Is move assignable throwing no exception(class template ) |
is_nothrow_move_constructible | Is move constructible throwing no exceptions(class template ) |
Type relationships
is_base_of | Is base class of(class template ) |
is_convertible | Is convertible(class template ) |
is_same | Is same type(class template ) |
Property queries
alignment_of | Alignment of(class template ) |
extent | Array dimension extent(class template ) |
rank | Array rank(class template ) |
Type transformations
Const-volatile qualifications
add_const | Add const qualification(class template ) |
add_cv | Add const volatile qualification(class template ) |
add_volatile | Add volatile qualification(class template ) |
remove_const | Remove const qualification(class template ) |
remove_cv | Remove cv qualification(class template ) |
remove_volatile | Remove volatile qualification(class template ) |
Compound type alterations
add_pointer | Add pointer(class template ) |
add_lvalue_reference | Add lvalue reference(class template ) |
add_rvalue_reference | Add rvalue reference(class template ) |
decay | Decay type(class template ) |
make_signed | Make signed(class template ) |
make_unsigned | Make unsigned(class template ) |
remove_all_extents | Remove all array extents(class template ) |
remove_extent | Remove array extent(class template ) |
remove_pointer | Remove pointer(class template ) |
remove_reference | Remove reference(class template ) |
underlying_type | Underlying type of enum(class template ) |
Other type generators
aligned_storage | Aligned storage(class template ) |
aligned_union | Aligned union(class template ) |
common_type | Common type(class template ) |
conditional | Conditional type(class template ) |
enable_if | Enable type if condition is met(class template ) |
result_of | Result of call(class template ) |
测试
#include <iostream>
#include <typeinfo>
#include <type_traits>
#include <string>
#include <complex>
using namespace std;
template <typename T>
void type_traits_output(const T& x)
{
cout << "\ntyoe traitd for type : " << typeid(T).name() << endl;
cout << "is_array\t" << is_array<T>::value << endl;
cout << "is_class\t" << is_class<T>::value << endl;
cout << "is_enum\t" << is_enum<T>::value << endl;
cout << "is_floating_point\t" << is_floating_point<T>::value << endl;
cout << "is_function\t" << is_function<T>::value << endl;
cout << "is_integral\t" << is_integral<T>::value << endl;
cout << "is_lvalue_reference\t" << is_lvalue_reference<T>::value << endl;
cout << "is_member_function_pointer\t" << is_member_function_pointer<T>::value << endl;
cout << "is_member_object_pointer\t" << is_member_object_pointer<T>::value << endl;
cout << "is_pointer\t" << is_pointer<T>::value << endl;
cout << "is_rvalue_reference\t" << is_rvalue_reference<T>::value << endl;
cout << "is_union\t" << is_union<T>::value << endl;
cout << "is_void\t" << is_void<T>::value << endl;
cout << "is_arithmetic\t" << is_arithmetic<T>::value << endl;
cout << "is_compound\t" << is_compound<T>::value << endl;
cout << "is_fundamental\t" << is_fundamental<T>::value << endl;
cout << "is_member_pointer\t" << is_member_pointer<T>::value << endl;
cout << "is_object\t" << is_object<T>::value << endl;
cout << "is_reference\t" << is_reference<T>::value << endl;
cout << "is_scalar\t" << is_scalar<T>::value << endl;
cout << "is_abstract\t" << is_abstract<T>::value << endl;
cout << "is_const\t" << is_const<T>::value << endl;
cout << "is_empty\t" << is_empty<T>::value << endl;
cout << "is_pod\t" << is_pod<T>::value << endl;
cout << "is_polymorphic\t" << is_polymorphic<T>::value << endl;
cout << "is_literal_type\t" << is_literal_type<T>::value << endl;
cout << "is_signed\t" << is_signed<T>::value << endl;
cout << "is_standard_layout\t" << is_standard_layout<T>::value << endl;
cout << "is_trivial\t" << is_trivial<T>::value << endl;
cout << "is_trivially_copyable\t" << is_trivially_copyable<T>::value << endl;
cout << "is_unsigned\t" << is_unsigned<T>::value << endl;
cout << "is_volatile\t" << is_volatile<T>::value << endl;
cout << "has_virtual_destructor\t" << has_virtual_destructor<T>::value << endl;
cout << "is_constructible\t" << is_constructible<T>::value << endl;
cout << "is_copy_assignable\t" << is_copy_assignable<T>::value << endl;
cout << "is_copy_constructible\t" << is_copy_constructible<T>::value << endl;
cout << "is_destructible\t" << is_destructible<T>::value << endl;
cout << "is_default_constructible\t" << is_default_constructible<T>::value << endl;
cout << "is_move_assignable\t" << is_move_assignable<T>::value << endl;
cout << "is_move_constructible\t" << is_move_constructible<T>::value << endl;
cout << "is_trivially_constructible\t" << is_trivially_constructible<T>::value << endl;
cout << "is_trivially_copy_assignable\t" << is_trivially_copy_assignable<T>::value << endl;
cout << "is_trivially_copy_constructible\t" << is_trivially_copy_constructible<T>::value << endl;
cout << "is_trivially_destructible\t" << is_trivially_destructible<T>::value << endl;
cout << "is_trivially_default_constructible\t" << is_trivially_default_constructible<T>::value << endl;
cout << "is_trivially_move_assignable\t" << is_trivially_move_assignable<T>::value << endl;
cout << "is_trivially_move_constructible\t" << is_trivially_move_constructible<T>::value << endl;
cout << "is_nothrow_constructible\t" << is_nothrow_constructible<T>::value << endl;
cout << "is_nothrow_copy_assignable\t" << is_nothrow_copy_assignable<T>::value << endl;
cout << "is_nothrow_copy_constructible\t" << is_nothrow_copy_constructible<T>::value << endl;
cout << "is_nothrow_destructible\t" << is_nothrow_destructible<T>::value << endl;
cout << "is_nothrow_default_constructible\t" << is_nothrow_default_constructible<T>::value << endl;
cout << "is_nothrow_move_assignable\t" << is_nothrow_move_assignable<T>::value << endl;
cout << "is_nothrow_move_constructible\t" << is_nothrow_move_constructible<T>::value << endl;
}
string 测试
int main()
{
type_traits_output(string());
return 0;
}
输出:
is_void 0
is_arithmetic 0
is_compound 1
is_fundamental 0
is_member_pointer 0
is_object 1
is_reference 0
is_scalar 0
is_abstract 0
is_const 0
is_empty 0
is_pod 0
is_polymorphic 0
is_literal_type 0
is_signed 0
is_standard_layout 1
is_trivial 0
is_trivially_copyable 0
is_unsigned 0
is_volatile 0
has_virtual_destructor 0
is_constructible 1
is_copy_assignable 1
is_copy_constructible 1
is_destructible 1
is_default_constructible 1
is_move_assignable 1
is_move_constructible 1
is_trivially_constructible 0
is_trivially_copy_assignable 0
is_trivially_copy_constructible 0
is_trivially_destructible 0
is_trivially_default_constructible 0
is_trivially_move_assignable 0
is_trivially_move_constructible 0
is_nothrow_constructible 1
is_nothrow_copy_assignable 0
is_nothrow_copy_constructible 0
is_nothrow_destructible 1
is_nothrow_default_constructible 1
is_nothrow_move_assignable 1
is_nothrow_move_constructible 1
complex 测试
int main()
{
type_traits_output(complex<float>());
return 0;
}
输出:
tyoe traitd for type : St7complexIfE
is_array 0
is_class 1
is_enum 0
is_floating_point 0
is_function 0
is_integral 0
is_lvalue_reference 0
is_member_function_pointer 0
is_member_object_pointer 0
is_pointer 0
is_rvalue_reference 0
is_union 0
is_void 0
is_arithmetic 0
is_compound 1
is_fundamental 0
is_member_pointer 0
is_object 1
is_reference 0
is_scalar 0
is_abstract 0
is_const 0
is_empty 0
is_pod 0
is_polymorphic 0
is_literal_type 1
is_signed 0
is_standard_layout 1
is_trivial 0
is_trivially_copyable 1
is_unsigned 0
is_volatile 0
has_virtual_destructor 0
is_constructible 1
is_copy_assignable 1
is_copy_constructible 1
is_destructible 1
is_default_constructible 1
is_move_assignable 1
is_move_constructible 1
is_trivially_constructible 0
is_trivially_copy_assignable 1
is_trivially_copy_constructible 1
is_trivially_destructible 1
is_trivially_default_constructible 0
is_trivially_move_assignable 1
is_trivially_move_constructible 1
is_nothrow_constructible 1
is_nothrow_copy_assignable 1
is_nothrow_copy_constructible 1
is_nothrow_destructible 1
is_nothrow_default_constructible 1
is_nothrow_move_assignable 1
is_nothrow_move_constructible 1
list 测试
int main()
{
type_traits_output(list<int>());
return 0;
}
输出:
tyoe traitd for type : NSt7__cxx114listIiSaIiEEE
is_array 0
is_class 1
is_enum 0
is_floating_point 0
is_function 0
is_integral 0
is_lvalue_reference 0
is_member_function_pointer 0
is_member_object_pointer 0
is_pointer 0
is_rvalue_reference 0
is_union 0
is_void 0
is_arithmetic 0
is_compound 1
is_fundamental 0
is_member_pointer 0
is_object 1
is_reference 0
is_scalar 0
is_abstract 0
is_const 0
is_empty 0
is_pod 0
is_polymorphic 0
is_literal_type 0
is_signed 0
is_standard_layout 0
is_trivial 0
is_trivially_copyable 0
is_unsigned 0
is_volatile 0
has_virtual_destructor 0
is_constructible 1
is_copy_assignable 1
is_copy_constructible 1
is_destructible 1
is_default_constructible 1
is_move_assignable 1
is_move_constructible 1
is_trivially_constructible 0
is_trivially_copy_assignable 0
is_trivially_copy_constructible 0
is_trivially_destructible 0
is_trivially_default_constructible 0
is_trivially_move_assignable 0
is_trivially_move_constructible 0
is_nothrow_constructible 1
is_nothrow_copy_assignable 0
is_nothrow_copy_constructible 0
is_nothrow_destructible 1
is_nothrow_default_constructible 1
is_nothrow_move_assignable 1
is_nothrow_move_constructible 1
自定义类测试
class Goo
{
public:
virtual ~Goo()
{ }
private:
int d1;
int d2;
};
int main()
{
type_traits_output(Goo());
return 0;
}
输出:
tyoe traitd for type : 3Goo
is_array 0
is_class 1
is_enum 0
is_floating_point 0
is_function 0
is_integral 0
is_lvalue_reference 0
is_member_function_pointer 0
is_member_object_pointer 0
is_pointer 0
is_rvalue_reference 0
is_union 0
is_void 0
is_arithmetic 0
is_compound 1
is_fundamental 0
is_member_pointer 0
is_object 1
is_reference 0
is_scalar 0
is_abstract 0
is_const 0
is_empty 0
is_pod 0
is_polymorphic 1
is_literal_type 0
is_signed 0
is_standard_layout 0
is_trivial 0
is_trivially_copyable 0
is_unsigned 0
is_volatile 0
has_virtual_destructor 1
is_constructible 1
is_copy_assignable 1
is_copy_constructible 1
is_destructible 1
is_default_constructible 1
is_move_assignable 1
is_move_constructible 1
is_trivially_constructible 0
is_trivially_copy_assignable 0
is_trivially_copy_constructible 0
is_trivially_destructible 0
is_trivially_default_constructible 0
is_trivially_move_assignable 0
is_trivially_move_constructible 0
is_nothrow_constructible 1
is_nothrow_copy_assignable 1
is_nothrow_copy_constructible 1
is_nothrow_destructible 1
is_nothrow_default_constructible 1
is_nothrow_move_assignable 1
is_nothrow_move_constructible 1
自定义类测试
class Zoo
{
public:
Zoo(int it1, int it2) : d1(it1), d2(it2)
{ }
Zoo(const Zoo&) = delete;
Zoo(Zoo&&) = default;
Zoo& operator=(const Zoo&) = default;
Zoo& operator=(const Zoo&&) = delete;
virtual ~Zoo()
{ }
private:
int d1;
int d2;
};
int main()
{
type_traits_output(Zoo(1, 2));
return 0;
}
输出:
tyoe traitd for type : 3Zoo
is_array 0
is_class 1
is_enum 0
is_floating_point 0
is_function 0
is_integral 0
is_lvalue_reference 0
is_member_function_pointer 0
is_member_object_pointer 0
is_pointer 0
is_rvalue_reference 0
is_union 0
is_void 0
is_arithmetic 0
is_compound 1
is_fundamental 0
is_member_pointer 0
is_object 1
is_reference 0
is_scalar 0
is_abstract 0
is_const 0
is_empty 0
is_pod 0
is_polymorphic 1
is_literal_type 0
is_signed 0
is_standard_layout 0
is_trivial 0
is_trivially_copyable 0
is_unsigned 0
is_volatile 0
has_virtual_destructor 1
is_constructible 0
is_copy_assignable 1
is_copy_constructible 0
is_destructible 1
is_default_constructible 0
is_move_assignable 0
is_move_constructible 1
is_trivially_constructible 0
is_trivially_copy_assignable 0
is_trivially_copy_constructible 0
is_trivially_destructible 0
is_trivially_default_constructible 0
is_trivially_move_assignable 0
is_trivially_move_constructible 0
is_nothrow_constructible 0
is_nothrow_copy_assignable 1
is_nothrow_copy_constructible 0
is_nothrow_destructible 1
is_nothrow_default_constructible 0
is_nothrow_move_assignable 0
is_nothrow_move_constructible 1
type traits 实现
is_void (范特化与偏特化)
/// remove_const
template<typename _Tp>
struct remove_const
{ typedef _Tp type; };
template<typename _Tp>
struct remove_const<_Tp const>
{ typedef _Tp type; };
/// remove_volatile
template<typename _Tp>
struct remove_volatile
{ typedef _Tp type; };
template<typename _Tp>
struct remove_volatile<_Tp volatile>
{ typedef _Tp type; };
/// remove_cv
template<typename _Tp>
struct remove_cv
{
typedef typename
remove_const<typename remove_volatile<_Tp>::type>::type type;
};
//...
template<typename>
struct __is_void_helper
: public false_type { };
template<>
struct __is_void_helper<void>
: public true_type { };
/// is_void
template<typename _Tp>
struct is_void
: public __is_void_helper<typename remove_cv<_Tp>::type>::type
{ };
is_integral (范特化与偏特化)
template<typename>
struct __is_integral_helper
: public false_type { };
template<>
struct __is_integral_helper<bool>
: public true_type { };
template<>
struct __is_integral_helper<char>
: public true_type { };
template<>
struct __is_integral_helper<signed char>
: public true_type { };
template<>
struct __is_integral_helper<unsigned char>
: public true_type { };
#ifdef _GLIBCXX_USE_WCHAR_T
template<>
struct __is_integral_helper<wchar_t>
: public true_type { };
#endif
template<>
struct __is_integral_helper<char16_t>
: public true_type { };
template<>
struct __is_integral_helper<char32_t>
: public true_type { };
template<>
struct __is_integral_helper<short>
: public true_type { };
template<>
struct __is_integral_helper<unsigned short>
: public true_type { };
template<>
struct __is_integral_helper<int>
: public true_type { };
template<>
struct __is_integral_helper<unsigned int>
: public true_type { };
template<>
struct __is_integral_helper<long>
: public true_type { };
template<>
struct __is_integral_helper<unsigned long>
: public true_type { };
template<>
struct __is_integral_helper<long long>
: public true_type { };
template<>
struct __is_integral_helper<unsigned long long>
: public true_type { };
// ...
/// is_integral
template<typename _Tp>
struct is_integral
: public __is_integral_helper<typename remove_cv<_Tp>::type>::type
{ };
is_class, is_union, is_enum, is_pod
/// integral_constant
template<typename _Tp, _Tp __v>
struct integral_constant
{
static constexpr _Tp value = __v;
typedef _Tp value_type;
typedef integral_constant<_Tp, __v> type;
constexpr operator value_type() const noexcept { return value; }
}
// ...
/// is_class
template<typename _Tp>
struct is_class
: public integral_constant<bool, __is_class(_Tp)>
{ };
/// is_union
template<typename _Tp>
struct is_union
: public integral_constant<bool, __is_union(_Tp)>
{ };
/// is_enum
template<typename _Tp>
struct is_enum
: public integral_constant<bool, __is_enum(_Tp)>
{ };
/// is_pod
// Could use is_standard_layout && is_trivial instead of the builtin.
template<typename _Tp>
struct is_pod
: public integral_constant<bool, __is_pod(_Tp)>
{ };
注: __is_xxx 未出现在 C++ 标准库源代码(可能为标准库提供了支持)
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。