c++标准库第五章通用工具5.1Pari和Tuple

一、pair 提供了直接访问对应数据成员的能力,因为pair是struct而不是class,默认所有成员都是public

二、所有元素都相等,这两个pair对象才相等

三、如果first相等,才继续比较second

四、pair的copy构造函数有两个版本

1、版本1接受相同类型的pair

2、版本2是个member template,在“构造过程中需要隐式类型转换”时被调用

五、如果pair对象被复制,调用的是被隐式合成的那个copy构造函数

六、只有piecewise_construct作为第一实参,且后面两个实参都是tuple时时,才会调用pair的第三个构造函数

七、可以使用get()获取first或second

八、可以使用tuple_size<>::value获取元素个数。可以使用tuple_element<>::type获取元素类型

九、c++11开始,可以使用move semantic或reference semantic来影响make_pair()产出的类型

1、move semantic。 使用std::move()声明被传递的实参不再使用

2、reference semantic。使用ref()强迫形成一个reference类型,或使用cref()强迫形成一个const reference类型

十、c++11开始,可以使用定义于内的tie()接口,抽取出pair的value

十一、tuple是TR1引入的,由于TR1用的是c++98特性,即不可能定义出一个“参数个数不定”的template,所以实际是有限的。c++11开始,引入了variadic template,使template得以接受任何数量的template实参

十二、tuple不允许迭代元素,可以使用get获取元素。必须再编译期传入索引值,如果在运行期才传入索引值,编译器会报错

十三、reference_wrapper<>以及ref(), cref()可以影响make_tuple()产生的类型

十四、使用reference搭配make_tuple可以提取tuple的元素值。方便的做法是tie(),使用它tie()时,使用std::ignore允许忽略tuple的某些元素

十五、可以使用tuple_cat()串接tuple,pair<>也可以

//---------------------pair start--------------------------------
// pair 提供了直接访问对应数据成员的能力,因为pair是struct而不是class,默认所有成员都是public
/*template<typename T1, typename T2>
struct pair
{
	T1 first;
	T2 second;
	pair(const T1& x, const T2& y);
	template<typename U, typename V>
	pair(U&& x, V&& y);
	template<typename...Args1, typename...Args2>
	pair(piecewise_construct_t, tuple<Args1...> first_args, tuple<Args2...> second_args);
};*/
/*template<typename T1, typename T2>
pair<V1, V2> make_pair(T1&& x, T2&& y);*/
/*template<typename T1, typename T2>
bool operator==(const pair<T1, T2>& x, const pair<T1, T2>& y)
{
	// 所有元素都相等,这两个pair对象才相等
	return x.first == y.first && x.second == y.second;
}*/
/*template <typename T1, typename T2>
bool operator<(const pair<T1, T2>& x, const pair<T1, T2>& y)
{
	// 如果first相等,才继续比较second
	return x.first < y.first || (!(y.first < x.first) && x.second < y.second);
}*/

void f(std::pair<int, const char*> ic)
{
	cout << "key: " << ic.first << "value:" << ic.second << endl;
}
void g(std::pair<const int, string> is)
{
	cout << "key: " << is.first << "value:" << is.second << endl;
}
void foo()
{
	//pair的copy构造函数有两个版本
	//版本1接受相同类型的pair
	//版本2是个member template,在“构造过程中需要隐式类型转换”时被调用
	//如果pair对象被复制,调用的是被隐式合成的那个copy构造函数
	std::pair<int, const char*> p(42, "hello");
	f(p); //调用的是被隐式合成的那个构造函数
	g(p);//调用的是template构造函数
	f(std::make_pair(42, "empty"));
	g(std::make_pair(42, "empty"));
	//c++11开始,也可以使用初值列
	f({ 42, "empty" });
	g({ 42, "empty" });
}

class PairConstructTest
{
public:
	PairConstructTest(tuple<int, float>)
	{
		cout << "PairConstructTest::PairConstructTest(tuple)" << endl;
	}
	template<typename...Args>
	PairConstructTest(Args... args)
	{
		cout << "PairConstructTest::PairConstructTest(args...)" << endl;
	}
};
void testPairConstruct()
{
	tuple<int, float> t(1, 2.22);
	pair<int, PairConstructTest> p1(42, t);
	// 只有piecewise_construct作为第一实参,且后面两个实参都是tuple时时,才会调用pair的第三个构造函数
	pair<int, PairConstructTest> p2(piecewise_construct, make_tuple(42), t);
}

void pairLearn()
{
	typedef std::pair<int, float> intFloatPair;
	intFloatPair p(42, 3.14);
	//可以使用get()获取first或second
	std::get<0>(p); // p.first
	std::get<1>(p); // p.second
	//可以使用tuple_size<>::value获取元素个数
	std::tuple_size<intFloatPair>::value;
	//可以使用tuple_element<>::type获取元素类型
	std::tuple_element<0, intFloatPair>::type;

	//c++11开始,可以使用move semantic或reference semantic来影响make_pair()产出的类型
	//move semantic。 使用std::move()声明被传递的实参不再使用
	string s = "hello";
	string t = "world";
	std::make_pair(std::move(s), std::move(t));
	//reference semantic。使用ref()强迫形成一个reference类型,或使用cref()强迫形成一个const reference类型
	int i = 0;
	int j = 0;
	std::make_pair(std::ref(i), ref(j));
	//c++11开始,可以使用定义于<tuple>内的tie()接口,抽取出pair的value
	std::pair<char, char> pc = std::make_pair('x', 'y');
	char resc;
	std::tie(std::ignore, resc) = p;
}
//---------------------pair end--------------------------------

//---------------------tuple start--------------------------------
template<typename... Types>
/*class tuple
{
public:
	// 接受不定个数的实参的构造函数时explicit的
	explicit tuple(const Types&...);
	template<typename... UTypes>
	explicit tuple(UTypes&...);
};*/
void tupleLearn()
{
	//tuple是TR1引入的,由于TR1用的是c++98特性,即不可能定义出一个“参数个数不定”的template,所以实际是有限的
	//c++11开始,引入了variadic template,使template得以接受任何数量的template实参
	tuple<int, float, string> t1(42, 6.3, "hello");
	// tuple不允许迭代元素,可以使用get获取元素
	// 必须再编译期传入索引值,如果在运行期才传入索引值,编译器会报错
	//int i;
	//get<i>(t1); // 报错
	cout << std::get<0>(t1) << " ";
	cout << std::get<1>(t1) << " ";
	cout << std::get<2>(t1) << " ";
	cout << endl;

	auto t2 = make_tuple(22, 44, "hello");
	cout << std::get<0>(t2) << " ";
	cout << std::get<1>(t2) << " ";
	cout << std::get<2>(t2) << " ";
	cout << endl;

	//reference_wrapper<>以及ref(), cref()可以影响make_tuple()产生的类型
	string s("my value");
	auto x = make_tuple(s);
	std::get<0>(x) = "my value x";
	cout << "x:" << std::get<0>(x) << " s:" << s << endl;
	auto y = make_tuple(ref(s)); 
	std::get<0>(y) = "my value y"; // 同时修改了s的值
	cout << "y:" << std::get<0>(y) << " s:" << s << endl;

	tuple<int, float, string> t3(42, 3.14, "hello");
	int t3i;
	float t3f;
	string t3s;
	// 使用reference搭配make_tuple可以提取tuple的元素值
	//make_tuple(ref(t3i), ref(t3f), ref(t3s)) = t3;
	//方便的做法是tie()
	std::tie(t3i, t3f, t3s) = t3;
	cout << " t3i: " << t3i << endl;
	cout << " t3f: " << t3f << endl;
	cout << " t3s: " << t3s << endl;
	cout << endl;
	//使用它tie()时,使用std::ignore允许忽略tuple的某些元素
	int t3i1;
	string t3s1;
	std::tie(t3i1, std::ignore, t3s1) = t3;;
	cout << " t3i1: " << t3i1 << endl;
	cout << " t3s1: " << t3s1 << endl;
	cout << endl;

	// 可以使用tuple_cat()串接tuple,pair<>也可以
	auto tcat = tuple_cat(t1, t2);
	cout << std::get<0>(t2) << endl;
}
//---------------------tuple end--------------------------------

int main()
{

	pairLearn();

	testPairConstruct();

	tupleLearn();
	
	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值