C++11学习笔记 16.docx
- 文档编号:13107247
- 上传时间:2023-06-11
- 格式:DOCX
- 页数:31
- 大小:32.68KB
C++11学习笔记 16.docx
《C++11学习笔记 16.docx》由会员分享,可在线阅读,更多相关《C++11学习笔记 16.docx(31页珍藏版)》请在冰点文库上搜索。
C++11学习笔记16
tuple是类型pair的模板。
不同tuple类型的成员类型也不同,但一个tuple可以有任意数量的成员。
每个确定的tuple类型的成员数目是固定的。
当我们希望将一些数据组合成单一对象,但有不想麻烦地定义一个新数据结构来表示时,tuple是非常有用的。
(“快速而随意”的数据结构)
tuple类型及其伴随类型和函数都定义在tuple头文件中。
tuple
所有成员都进行值初始化。
tuple
make_tuple(v1,v2,...,vn) 返回给定初始值初始化的tuple,并进行类型推断。
== !
= 关系运算符
get(t) 返回t的第i个数据成员的引用;如果t是一个左值,结果是一个左值引用;否则,是右值引用。
tuple的所有成员都是public的,i是一个整型常量。
tuple_size
:
value 一个类模板,可以通过一个tuple类型类初始化。
它有一个名为value的publicconstexprstatic数据成员,类型为size_t,表示给定tuple类型中成员的数量。
teple_element:
:
type 一个类模板,可以通过一个整型常量和一个tuple类型来初始化。
它有一个名为type的public成员,表示给定tuple类型中指定成员的类型。
如果不知道一个tuple的准确的类型细节,可以用两个辅助类模板来查询tuple的成员的数量和类型:
typedefdecltype(item)trans;
size_tsz=tuple_size
:
value;
tuple_element<1,trans>:
:
typecnt=get<1>(item);
为了使用关系运算符,对没对成员使用<必须都是合法的。
由于tuple定义了<和==运算符,我们可以将tuple序列传递给算法,并且可以再无心容器中将tuple作为关键字类型。
tuple常用的以个用途是从一个函数返回多个值。
//matches有三个成员:
一家书店的索引和两个指向书店vector中元素的迭代器
typedeftuple
:
size_type,vector
:
const_iterator,vector
:
cosnt_iterator>matches;
vector
{
vector
for(autoit=files.cbegin();it!
=files,cend();++it)
{
autofound=equal_range(it->cbegin(),it->cend(),book,compareIsbn);
if(found.first!
=found.second)
ret.push_back(make_tuple(it-files.cbegin(),found.first,found.second));
}
returnret;
}
voidreportResults(istream&in,ostream&os,constvector
{
strings;
while(in>>s)
{
autotrans=findBook(files,s);
if(trans.empty())
{
cout<
continue;
}
for(consttuto&stre:
trans)
os<<"stre"<
"
<
< } } 标准库还定义了bitset类,使得为运算的使用更为容易,并且能够处理超级最长整型类型大小的位集合。 bitset类定义在头文件bitset中。 类似于数组。 变化从0开始的二进制位被称为低位,左后结束的二进制位被称为高位。 bitset bitset 如果n大于unsignedlonglong的大小,则b中超出unsignedlonglong的高位被设置为0。 此构造函数时以个constexpr。 初始值中多出的高位被丢弃。 bitset s只能包含字符zero和one;如果s包含任何其他字符,构造函数抛出invalid_argument异常。 字符在b中分别保存为zero和one。 pos默认为0,m默认为string: : npos,zero默认为'0',one默认为'1' bitset 如果未提供m,则cp必须指向一个C风格字符串串。 如果提供了m,则从cp开始必须至少有m个zero或one字符 注意: 接受一个string或一个字符指针的构造函数时explicit的。 在新标准中增加了为0和1指定其他字符的功能。 对于string的下标编号习惯与bitset加好相反: string中下标最大的字符(最右字符)用来初始化bitset中的低位(下标为0的二进制位)。 当你用一个string初始化一个bitset时,要记住这个差别。 bitset还支持位运算符。 这些运算符用于bitset对象的含义与内置运算符用于unsigned运算对象相同。 b.any() b中时否存在置位(即等于1)的二进制位。 b.all() b中所有的位都置位了吗 b.none() b中不存在置位的二进制位吗 b.count() b中置位的位数 b.size() 一个constexper函数,返回b中的位数 b.test(pos) 若pos位置的是位置的,则返回true,否则返回false b.set(pos,v) 将位置pos处的位设置为bool值v。 v默认为true。 如果未传递实参,则将b中所有位置位 b.set() b.reset(pos) 将pos处的位复位或将b中所有位复位 b.reset() b.flip(pos) 改变位置pos处的位的状态或改变b中每一位的状态 b.flip() b[pos] 访问b中位置pos处的位;如果b是const,则当该位置位是b[pos]返回一个bool值true,否则返回false;非const版本返回bitset定义的一个特殊类型,它允许我们曹总指定位的值 b.to_ulong() 返回一个unsignedlong或一个unsignedlonglong值,其位模式雨b相同。 如果b中位模式不能放入指定的结果类型,则抛出一个overflow_error异常 b.to_ullong() b.to_string(zero,one)返回一个string,表示b中的位模式。 zero和one的默认分别是0、1,用来表示b中的0、1 os< is>>b 从is读取字符存入b。 当下一个字符不是1或0是,或是已经读入b.size()个位时,读取过程停止 正则表达式是一种描述字符列的方法,是一种极其强大的技术工具。 RE库定义在头文件regex中,它包含多个组件: regex 表示有一个正则表达式的类 regex_match 将一个字符序列与一个正则表达式匹配,如果输入序列与表达式匹配则regex_match函数返回true regex_search 寻找第一个与正则表达式匹配的子序列 如果输入序列中一个子串与表达式匹配,则regex_search函数返回true regex_replace 使用给定格式替换一个正则表达式 sregex_iterator 迭代器适配器,调用regex_search来遍历一个string中所匹配的字串 smatch 容器类,保存在string中搜索的结果 ssub_match string中匹配的子表达式的结果 regex、search和regex_match的参数: 注: 这些操作返回bool值,指出是否找到匹配 (seq,m,r,mft) (seq,r,mft) 在字符seq中查找regex对象r中的正则表达式。 seq可以是一个string、表示范围的一对迭代器以及一个指向空字符结尾的字符数组的指针 m是一个match对象,用来保存匹配结果的相关细节。 m和seq必须具有兼容的类型。 mft是一个可选的regex_constants: : match_flag_type值。 他们会影响匹配过程 //查找违法众所周知的拼写规则“i除非在c之后,否则必须在e之前“的单词 //查找不在字符c之后的字符串ei stringpattren("[^c]ei"); //我们必须包含pattern的整个单词 pattern="[[: alpha: ]]*"+pattern+"[[: alpha: ]]*"; regexr(pattern); //构造一个用于查找模式的regex smatch results; //定义一个对象保存搜索结果 //定义一个string保存于模式匹配和不匹配的文本 stringtest_str="receiptfreindtheifreceive"; //用r在test_str中炒作与pattern匹配的子串 if(regex_search(test_str,results,r)) //如果有匹配 cout< 正则表达式[^c]表明我们希望匹配任意不是‘c'的字符,而[^c]ei指出我们想要陪陪这种字符后接ei的字符串。 此模式包含了三个字符。 为了与整个单词匹配,我们还需要一个正则表达式与这个三个字母模式之前和之后的字母匹配。 这个正则表达式包含零个或多个字母后接我们的三字母的模式,然后在接零个或多个额外的字母。 默认情况下,regex使用的正则表达式语言是ECMAScript。 在ECMAScript中,模式[[: alpha: ]]匹配任意字母,符号+和*分别表示我们希望“一个或多个”或“零个或多个”匹配。 因此[[: : alpha: : ]]*将匹配零个或多个字母。 当我们定义一个regex或是对一个regex调用assign为其赋予新值时,可以知道那个一些标志来影响regex如何操作。 可行标志控制regex对象的处理过程。 对于这6个标志,我们必须设置其中之一,且只能设置一个。 默认情况下,ECMAScript标志被这只,从而regex会使用ECMA-262规范,这也是Web浏览器所使用的正则表达式语言。 regex(和wregex)选项: regexr(re) regexr(re,f) re表示一个正则表达式,它可以是一个string、一个表示字符范围的迭代器对、一个指向空字符结尾的字符数组的指针、一个字符指针和一个计数器或是一个花括号包围的字符列表。 f是指出对象如何处理的标志。 f通过下面列出的值来设置。 如果为指定f,其默认值为ECMAScript r1=re 将r1中的正则表达式替换为re。 re表示一个正则表达式,它可以是另一个regex对象、一个string、一个指向空字符结尾的字符数组的指针或是一个或括号保卫的字符列表。 r1.assign(re,f) 与使用复制运算符(=)效果相同 r.flags() 返回r的标志集 注: 构造函数和赋值操作可能抛出类型为regex_error的异常 定义regex时指定的标志: (定义在regex和regex_constants: : syntax_option_type中) icase 在匹配过程中忽略大小写 nosubs 不保存匹配的子表达式 optimize 执行速度优先于构造速度 ECMAScript 使用ECMA-262指定的语法 basic 使用POSIX基本的正则表达式语法 extended 使用POSIX扩展的正则表达式语法 awk 使用POSIX版本的awk语言的语法 grep 使用POSIX版本的grep的语法 egrep 使用POSIX版本的egrep的语法 前三个标志允许我们指定正则表达式处理过程中与语言无关的方面。 例子,识别特定扩展名的文件名。 大多数操作系统都是按大小写无关的方式来识别扩展名的。 //一个或多个字母或数字字符后接一个'.'再接“cpp”或“cxx”或“cc” regexr("[[: alnum: ]]+\\.(cpp|cxx|cc)$",regex: : icase); smatchresults; stringfilename; while(cin>>filename) if(regex_search(filename,results,r)) cout< 此包大师将匹配这样的字符串: 一个或多个字母或数字后接一个句点在接三个文件扩展名之一。 这样,此正字表达式将会匹配指定的文件扩展名而不理会大小写。 和c++一样,正则表达式语言通常也有特殊字符。 字符点(.)通常匹配任意字符。 与c++一样,我们可以再字符之前放置一个反斜线来去掉其特殊含义。 由于反斜线也是c++中的一个特殊字符,我们在字符串字面常量中必须连续使用两个反斜线来告诉c++我们想要一个普通反斜线字符。 因此,为了表示与句点字符匹配的正则表达式,必须写成\\. 正则表达式本身看作用用一种简单程序设计语言编写的“程序”(非C++)。 正则表达式是在运行时,当一个regex对象被初始化或被赋予一个新模式是,才被“编译”的。 如果编写的正则表达式存在错误,则在运行时标准库会抛出一个类型为regex_error的异常。 类似标准异常类型,regex有一个what操作来描述发生了什么错误。 regex_error还有一个名为code的成员,用来返回某个错误类型对应的数值编码。 code返回的值是由具体实现定义的。 RE库能抛出的标准错误下所示。 正则表达式错误类型: (定义在regex和regex_constants: : error_type中) error_collate 无效的元素校对请求 error_ctype 无效的字符类 error_escape 无效的转义字符或无效的尾置转义 error_backref 无效的向后引用 error_brack 不匹配的方括号([]) error_paren 不匹配的小括号 error_brace 不匹配的花括号 error_badbrace {}中无效的范围 error_range 无效的字符范围(如[z-a]) error_space 内存不足,无法处理此正则表达式 error_badrepeat 重复字符(*、? 、+或{)之前没有有效的正则表达式 error_complexity 要求的匹配过于复杂 error_stack 栈空间不足,无法处理匹配 避免创建不必要的正则表达式: 一个正则表达式所表示的“程序”是在运行时而非编译时编译的。 正则表达式的编译是一个非常慢的操作,特别是在使用了扩展的正则表达式语法或是复杂的正则表达式时。 因此,构造一个regex对象以及想一个已存在的regex赋予一个新的正则表达式可能是非常耗时的。 为了最小化这种开销,你应该努力避免创建很多不必要regex。 特别是,如果你在一个循环中使用正则表达式,应该在循环外创建它,而不是在每步迭代时就编译它。 我们可以搜索多种类型输入序列。 重点在于我们使用RE库类型必须与输入序列类型匹配。 输入可以是普通char数据或wchar_t数据,字符可以保存在标准库string中或是char数组中(或是宽字符版本,wstring或wchar_t数组中)。 RE为这些不同的输入序列类型都定义了对应的类型。 下面给出了RE库类型与输入序列类型的对应关系。 如果输入序列类型 则使用正则表达式类 string regex、smatch,ssub_match,sregex_iterator constchar* regex,cmatch,csub_match,cregex_iterator wstring wregex,wsmatch,wssub_match,wsregex_iterator constwchar_t* wregex,wcmatch,wcsub_match,wcregex_iterator 我们可以使用sregex_iterator来获得所有匹配。 regex迭代器是一种迭代器适配器,被绑定到一个输入序列和一个regex对象上。 每种不同输入序列类型都有对应的特殊regex迭代器类型。 sregex_iterator操作,这些操作也适用于cregex_iterator、wsregex_iterator、wcregex_iterator sregex_iterator it(b,e,r); 一个sregex_iterator,遍历迭代器b和e表示的string。 sregex_iteratorend; sregex_iterator的尾后迭代器 *it it-> 根据最后一个调用regex_search的结果,返回一个smatch对象的引用或一个指向smatch对象的指针 ++it it++ 从输入序列当前匹配位置开始调用regex_search。 it1==it2 ! = 如果两sregex_iterator都是尾后迭代器,则它们相等,两个非尾后迭代器是从相同的输入序列和regex对象构造,则它们相等 当我们将一个sregex_iterator绑定到一个string和一个regex对象时,迭代器自动定位到给定string中第一个匹配位置。 当我们解引用时会得到一个对应最近一次搜索结果的smatch对象。 当我们递增迭代器是,它调用regex_search在输入序列string中查找下一个匹配。 例,这个版本的程序使用与前一个版本一样的pattern,但会使用一个sregex_iterator来进行搜索 stringpattern("[^c]ei"); pattern='[[: alpha: ]]+parrern+"[[: alpha: ]]*"; regexr(parrern,regex: : icase); for(sregex_iteratorit(file.begin(),file.end(),r),end_it;it! =end_it;++it) cout< smatch和ssub_match类型它们允许我们获得匹配的上下文。 匹配类型有两个名为prefix和suffix的成员,分别返回表示输入序列中当前匹配之前和之后部分的ssub_match对象。 一个ssub_match对象有两个名为str和length的成员,分别返回匹配的string和该string的大小。 我们可以用这些操作重写语法程序的循环: for(sregex_iteratorit(file.begin(),file.end(),r),end_it;it! =end_it;++it) { autopos=it->prefix().length(); pos=pos>40? pos-40: 0; //我们想要最多40个字符 cout< <<"\n\t\t>>>"< < < } smatch操作: (这些操作也使用于cmatch、wsmatch和对应的csub_match、wssub_match和wcsub_match) m.ready() 如果已经通过调用regex_serach或regex_match设置了m,则返回true;否则返回false。 如果ready返回false,则对m进行操作是未定义的 m.size()
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- C+11学习笔记 16 C+ 11 学习 笔记