2

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:

image.png

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++ 标准库源代码(可能为标准库提供了支持)


TianSong
734 声望138 粉丝

阿里山神木的种子在3000年前已经埋下,今天不过是看到当年注定的结果,为了未来的自己,今天就埋下一颗好种子吧