一、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;
}