《C++ Primer (5th Edition)》笔记-Part IV. Advanced Topics

注:本文以《C++ Primer(英文版)》(5th Edition)为参考。

总共由四部分组成:

《C++ Primer (5th Edition)》笔记-Part I. The Basics 
《C++ Primer (5th Edition)》笔记-Part II. The C++ Library
《C++ Primer (5th Edition)》笔记-Part III. Tools For Class Authors
《C++ Primer (5th Edition)》笔记-Part IV. Advanced Topics



Part IV. Advanced Topics

Chapter 17. Specialized Library Facilities

17.1 C++11引入了tuple类型。tuple与pair很像,但是tuple的成员个数不定,tuple的具体类型由元素个数和元素类型决定。tuple的默认构造函数value initialize其成员,tuple的构造是explicit,不能隐式转换。和pair一样,tuple也可以通过make_tuple来得到。

tuple<size_t, size_t, size_t> threeD = {1,2,3}; // error 
tuple<size_t, size_t, size_t> threeD{1,2,3}; // ok
17.2 tuple的成员函数只有构造函数和赋值操作符,tuple还支持关系操作符,tuple在做赋值或关系比较的时候,要求元素个数要一致(不要求元素类型一致),否则编译出错。另外,libary提供了模板get<i>(t)、tuple_size<tupleType>::value、tuple_element<i, tupleType>::type等来分别获取第i个元素、获得元素个数,获得第i个元素的类型。

17.3 template <size_t N> class bitset。小下标对应于低位,大下标对应于高位。构造函数接受unsigned long long类型或者字符串(string + iterator或者C串指针)。bitset支持IO操作符,具有转换为整型(若溢出,抛出overflow_error异常)或者字符串的成员函数:to_ulong()、to_ullong()、to_string(charZero, charOne),某位查询:test(pos), b[pos],整体查询:any(),all(),none(),count(),size(),其中all()是C++11新引入的新函数,count返回open的位的个数,size()返回bitset的总的位数,此函数为consexpr函数。某位设置或整体设置函数:set(pos, boolean), set(), reset(pos), reset(), flip(pos), flip()。

17.4 C++11加入了regular expression支持。主要由涉及的类有regex、smatch、ssub_match、sregex_iterator,主要涉及的函数:regex_match、regex_search、regex_replace。其中regex_match是匹配整个串,regex_search则是与串的子串进行匹配,但两者的参数列表都有两种形式:(str, match, reg, match_flag_type)、(str, reg, match_flag_type)。

// find the characters ei that follow a character other than c
string pattern("[^c]ei");
// we want the whole word in which our pattern appears
pattern = "[[:alpha:]]*" + pattern + "[[:alpha:]]*"; 
regex r(pattern); // construct a regex to find pattern
smatch results; // define an object to hold the results of a search 
// define a string that has text that does and doesn't match pattern
string test_str = "receipt freind theif receive";
// use r to find a match to pattern in test_str
if (regex_search(test_str, results, r)) // if there is a match
	cout << results.str() << endl; // print the matching word
17.5 regex内部有一个flag信息,在regex构造的时候指定,若不指定,就使用flag:ECMAScript,可以指定的flag值如下表所示。正则表达式对自己的特殊字符使用反斜杠转义,而C++还需要用反斜杠转义反斜杠,所以在字符串中通常是两个反斜杠一起出现。正则表达式就相当于一门简单的语言,在run time时被编译,而且很有可能编译出错(正则表达式写的有误),这时就会抛出regex_error错误,regex_error不仅有what成员函数,还有code成员函数,来返回error code,具体code的意义可参考P.732。
try {
	// error: missing close bracket after alnum; the constructor will throw 
	regex r("[[:alnum:]+\\.(cpp|cxx|cc)$", regex::icase);
} 
catch (regex_error e){ 
	cout << e.what() << "\ncode: " << e.code() << endl; 
}

17.6 正则表达可以接受C串或者string格式的char或者wchar_t字符串。但对不同类型的字符串应该使用相对应类型的类(操作都是一样的)。

17.7 正则表达式的匹配结果通常存放在smatch中,而smatch只能通过regex_search、regex_match、sregex_iterator来填充。smatch不仅保存匹配的结果,还保存匹配中group匹配的结果(作为ssub_match对象)。smatch.size()成员函数比较特殊,若匹配失败,返回0,否则返回1+subexpression的个数。smatch有一些以下标为参数的成员函数,若下标index为0(默认值),查询的是整体的匹配结果,否则,查询的是第index-1个subexpression的匹配结果。另外smatch的成员prefix()、suffix()返回分别代表匹配段之前、之后的字符串的ssub_match,所以,这两个函数对regex_match的结果没什么用处。sregex_iterator解引用后得到的是smatch,当sregex_iterator构造时,会调用regex_search得到匹配到的第一个smatch,当sregex_iterator自增时,也会调用regex_search得到下一个匹配结果。

string pattern("or");
regex r(pattern, regex::icase);
string str = "hey read or write according to the type";
for (sregex_iterator it(str.begin(), str.end(), r),end_it; it != end_it; ++it) {
	auto pos = it->prefix().length(); // size of the prefix
	pos = pos>10 ? pos-10 : 0; //we want up to 40 characters
	cout << it->prefix().str().substr(pos) // last part of the prefix
		<< "-" << it->str() << "-" // matched word
		<< it->suffix().str().substr(0, 10) // first part of the suffix
		<< endl;
}
17.8 正则表达式通常用一对括号来划分subexpression。通常用subexpression在做Data Validaion(根据某个subexpression是否又被匹配到,通常后面跟”?“),ssub_match也确实提供了matched公共数据成员。

17.9 在进行regex_replace时,通常需要和subexpression配合使用,在目标串格式中用”$"+subexpression编号(从1开始)的方式,来代表某个subexpression。不管是调用regex_search、regex_match还是regex_replace,都可以设置match_flag_type,每个match_flag_type的具体意义可以参考P.744。

17.10 在C++11之前,只能使用rand()来随机得到一个在0到system-dependent maximum value(RAND_MAX至少是32767)之间平均分布的整数。C++11中,提供了新的随机数支持,主要涉及两大类:random-number engines 和 random-number distribution。C++编程已经不提倡使用rand()函数了,可以用default_random_engine函数对象来代替。

17.11 random-number engines 都是(不是模板)函数对象,他们的调用操作符不接受参数(在构造函数中可接受种子,也可以通过seed(val)成员函数来设置种子),返回随机的无符号数。library定义了一些random-number engines ,他们在performance和“quality”上有差别。

17.12 random-number engine e返回的随机数的范围是[e.min(), e.max],当得到特定区间的随机数时,通常与random-number distribution类配合使用,library定义了20种distribution,其类型基本上都是模板函数对象,所以在使用时要显式给出类模板参数列表,但只有一中不是类模板:bernoulli_distribution,它是普通的函数对象。下面的代码中,由于没有为e设置种子,所以如果没有声明为静态变量的话,每次得到的结果将是一样的。通常的做法是用时间做种子,如default_random_engine e1(time(0));这里由于time()返回的时间的单位是秒,所以仅适用于秒级的应用。

// returns a vector of 100 uniformly distributed random numbers 
vector<unsigned> good_randVec(){
	// because engines and distributions retain state, they usually should be 
	// defined as static so that new numbers are generated on each call
	static default_random_engine e;
	static uniform_int_distribution<unsigned> u(0,9); 
	vector<unsigned> ret;
	for (size_t i = 0; i <
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值