跳转到内容

C++/Utility

维基教科书,自由的教学读本
< C++

<Utility> 是从C++11正式引入C++标准程式库中的一个头文件,定义了C++标准中几个不相关领域的工具:

[编辑]
  • Pairs: 可以保存两个不同类型值的对象: pair
    • make_pair:不需要指出模板参数类型,就可以构造pair,例如:make_pair(42,7.77)生成的是std::pair<int,double>实例
    • piecewise_construct_t是一个空类,用于辨识出pair::pair(piecewise_construct_t, tuple, tuple)
    • piecewise_construct是piecewise_construct_t的一个实例对象
  • template< class T > struct tuple_size,继承自std::integral_constant。用于在编译时获取给定std::tuple或std:;pair或std::array类型包含的元素数量。
    • template< class T > constexpr std::size_t tuple_size_v = tuple_size<T>::value; 为C++17引入。
  • template< std::size_t I, class T > struct tuple_element; 用于在编译时获取 std::tuple 中特定位置元素的类型信息。
    • template< std::size_t I, class T > using tuple_element_t = typename tuple_element<I, T>::type; 为C++17引入。
  • template< class T, T... Ints > class integer_sequence; 编译时整数序列。
    • template< std::size_t... Ints > using index_sequence = std::integer_sequence<std::size_t, Ints...>;
    • template< class T, T N > using make_integer_sequence = std::integer_sequence<T, /* a sequence 0, 1, 2, ..., N-1 */>;
    • template< std::size_t N > using make_index_sequence = std::make_integer_sequence<std::size_t, N>;
    • template< class... T > using index_sequence_for = std::make_index_sequence<sizeof...(T)>;

函数

[编辑]
  • Generic relational operators: 在特定命名空间rel_ops中给出了关系运算符 !=, >, <= , >=的标准定义.用户只需先行定义两个关系运算符==与<。
  • Rvalue casts (C++11): 允许产生右值引用: forward, move, move_if_noexcept, declval.
    • move_if_noexcept:返回实参对象的右值引用,如果参数类型是不抛出异常(nothrow guarantee)的移动可构造或是不可复制构造的;否则(除非复制比移动时更好的选择,至少有强异常安全保证),返回左值引用。 强异常安全保证(strong guarantee,strong exception safety),或称提交或卷回的语义(commit or rollback semantics),或无变化保证(no-change guarantee),是指运行可以是失败,但失败的运行保证不会有负效应,因此所有涉及的数据都保持代码运行前的初始值。
    • declval 函数模板:返回模板参数类型 T的右值引用但未绑定任何对象。用于不求值的运算符(unevaluated operands),如sizeof或decltype。T可以是不完整类型。 是帮助函数(helper function)用于引用类的成员,但该类的构造函数形参是未知的或是不可构造的类(如抽象基类)。 decltype 作用于表达式,返回表达式的类型;declval 作用于类型,返回该类型的表达式(准确的来说是该类型加上右值引用的类型)。declval 只能在编译期间生效的语句里,比如 decltype , sizeof 还有模板元编程中。否则会报错。由于不存在引用指针这种类型,所以如果T是引用类型时,decltype(*(T *)nullptr) j = m; //错误 由于在编译期使用,declval不需要类型T 有构造函数;另外,由于存在引用折叠,注意declval 最终表达式的类型。
  • Generic swap function: 通用的交换函数。STL库中,特别是容器,大量调用了swap函数,并采取未限定方式(unqualified manner)以允许用户对非基础类型自写的swap函数被STL重载调用。这通常是把非基础类型的声明与相关的swap函数声明放在同一个命名空间中,编译器通过依赖于实参的名字查找(argument-dependent lookup)即可调用这个重载版本。

例子程序

[编辑]
// swap algorithm example (C++11)
#include <iostream>     // std::cout
#include <utility>      // std::swap
using namespace std;

namespace foo{
struct int1 {
	int _val;
	int1(int p):_val(p) {};
};

void swap(int1& a, int1& b) 
{
	cout << "my swap" << endl;
	int1 i(a);
	a = b;
	b = i;
};
}
using namespace foo;

int main() {

	int1 x = 10, y = 20;                  // x:10 y:20
	swap(x, y);                  // x:20 y:10

	return 0;
}

参考文献

[编辑]