[声明]:本英文资料源自于Herb Sutter 发表于“C/C++ User Journal”杂志,“C++ 翻译小组”的翻译作品供学习交流与参考用途,不得用于任何商业用途。未经Herb Sutter同意,不得转载;对于违反以上条款,翻译小组对此不负任何责任;特此声明。
文章来源:http://www.gotw.ca
版权归属:Herb Sutter
译 者:Elminster (CSDN)
The New C++: 七人组-审议C++标准库扩展
上次[1],我概述了一下C++标准的过去、现在和未来可能的方向,主要的参与者、他们是如何相互影响以及如何影响你。正如这次承诺的,我将带领大家概观一下在2001年10月Redmond, Washington, USA举行的WG21/J16会议上审议的第一批建议库扩展。
[章程]
当你阅读下一部分的提议摘要时,请注意4件重要的事情:
现在没有最终决定,提议的第一个组织根本上要提供给“库工作组”一些有形东西来进行考虑。考虑实际的提议让我们更好的了解在一个协议中我们想要什么,什么样的问题我们应该能问的。
不是每一个提议都是必需的,这些提议中,许多是来自Boost[2],但是Boost并不是一个幸运儿。对于其他相同的提议,这扇门没有关闭。这只是一些接受到的例子,只是作为最初的考虑,“库工作组”知道大部分的提议都是具有竞争力的设计或实现。举个例子,有一个提议是Boost的“正则表达式”的功能,而微软研究院最近也提出了具有竞争力的、他们自己的“正则表达式”的功能,在某些方面表现更好。在这种情况下, “库工作组”可以选择采用其中之一、或每个提议的一部分、或者两个都不采用如果标准不需要包含特定类型的功能。
与标准兼容很重要:这意味着要兼容C++98,一般提议要能在当前的标准C++中执行。同时也意味着与其他标准兼容,特别是C99(比如,采用C99功能,像以下提及的它的头文件<stdint.h>)和POSIX(如在线程库提议中)。
可实现性的重要:我们考虑的所有提议都有参考的实现,可供“库工作组”成员检查。这在最初的1995的HP STL以后就成了惯例,委员会可以自由加入到标准的形式,提供了工作实现。
这是知道的3个主要类别,我们希望加入到C++标准库中的:
C99兼容:无论什么情况下如果有可能,我们都希望采用C99的功能,这样能促进两种语言更好的兼容。此外,C99的头文件<stdint.h>是一个突出的例子。
填补缺陷:我们希望加入的东西可以填补当前c++标准库的缺陷和遗漏。一个例子就是哈希容器。另一个就是智能指针的广泛的选择,除了当前的auto_ptr,不幸的是auto_ptr看起来用在不合适的地方,只是因为它仅仅是标准的智能指针;我们可以做的更好。
有用的功能:一个功能不会因为有用就一定要标准化。但是有些功能,比如广泛使用的字符串,如果它不标准化,那就很为难了。实际上就是因为这个原因C++98(不同与预标准化的C++)中加了字符串;不必放进标准的像是标准支持正则表达式式匹配和标记化,这些都是我们通常想在特别是字符串、迭代器范围、流上实施的任务。在这个类别中,还包括了简化系统编程和泛型编程作业功能,如下面讨论的线程和Type Traits等。
你将会看到这一组提议是这三类的代表。
[提议]
这里是7条提议
Header <cstdint> [3]
C99标准向C标准库中加了几个新的功能。特别是C99<stdint.h>头文件支持给定宽度的标准整型,这在代码跨平台移植方面有用。
精确宽度整数(C99中可选):intNN_t 和uint_NN_t,这里NN可以是8, 16, 32, 或 64 (如: int32_t),分别是signed 和unsigned整数,准确宽度NN位。
最小宽度整数:int_leastNN_t和uint_leastNN_t,这里NN可以是8, 16, 32, 或 64 (如: int_least32_t),分别是signed 和unsigned整数,最少NN位。
最快最小宽度整数:int_fastNN_t 和 uint_fastNN_t 这里 NN 可以是8, 16, 或 32 (例如 int_fast32_t)分别是signed 和unsigned整数,最少NN位,通常在大多数正数操作中是最快的。
最大宽度的整数:intmax_t 和 uintmax_t 分别是signed和unsigned 整数,分别能保存任何signed 或unsigned值。
这很有用因为现在多数商用的C++项目,目标都是多平台,我们已经定义了我们自己版本的这些功能为了更好的移植性。你可能已经在项目的公有系统头文件中有一个OUR_INT32 typedef或宏定义。像这些功能帮助我们避开重新改造太多基础的东西,特别是当我们要把代码移植到64位机上的时候,显得很有用。
Boost的头文件<cstdint>提供了typedef对这些C99类型的封装,把所有命名都放到Boost的命名空间里。如果被标准采用,大概这些命名将会出现在标准库的命名空间里。
Type Traits [4]
提交的第二个功能是Boost的Type Traits。如果你对类型的重要性有怀疑的话,请重新阅读Alexandrescu的“Modern C++ design” [5]。这本书的Loki库包括了与Boost相类似的功能,虽然细节不相同,一个具有优势,另一个没有。
写一个模板,模板参数T:
template<typename T>
void f( T t ) { /* whatever */ }
在这个函数模板里,你想知道类型T真是一个类(换句话说,是一个整型还是个函数)吗?问is_class<T>;想知道它是个成员指针吗?问is_member_pointer<T>;它是个浮点指针类型吗?is_float<T>会告诉你。还有更多。
在第一次提交考虑加入下一代C++标准库中的就有Type Traits功能,这表明在今天它是多么重要和多么经常手工使用。在标准之前,许多字符串有自己的basic_string模板,今天许多人使用自己的Type Traits功能。不管哪个提议最终被接受,拥有这一类功能将提供,正如我们现在意识到的,基本服务用于某些泛型编程
正则表达式[6]
正则表达式分解和匹配是许多项目每天做的事情之一。一些语言像Perl提供了超出一般的能力。Boost的正则表达式式匹配库提供了强大的工具,故意与Perl, POSIX, 其他流行的正则表达式库,相类似和兼容。如果你了解Perl的工具,你将可以不费吹灰之力使用Boost的工具。
这是一个简单的例子,来自库的自带文档,演示了如何检查是否一个普通的C++字符串存储了可读的信用卡号码。
bool validate_card_format(const std::string s)
{
static const boost::regex e("(\\d{4}[- ]){3}\\d{4}");
return regex_match(s, e);
}
正如我上面指出的,微软研究院也设计了一个具竞争的正则表达式功能,宣称与Boost相比具有重要的性能优势。另一些竞争的功能可能也会出现。我个人认为可能他们中的一个(或一些组合)被C++标准库采用,但是在这一点上,这个领域是敞开的。如果你有一个regex库,你认为比它们高级;你可以贴到新闻组comp.std.c++让我们知道。马上行动。
Smart Pointers [7]
正如上面解释的,auto_ptr是唯一的标准智能指针,这确实是耻辱。这不需要在发生了;真正的在第一轮C++标准化的过程中,特别是Greg Colvin几次鼓励提交智能指针变量,委员会只接受了auto_ptr,我们客气的讲就是“修改”形式。特别是Colvin的 counted_ptr没有放进标准。但是不要害怕,它在这里Boost:counted_ptr 现在叫 boost::shared_ptr ,有一个类似的shared_array。还有一个scoped_ptr,它可论证auto_ptr应该是什么(就是,限制当它越界时,自动对象释放它的指针)和补充的scoped_array。
当我们正在讨论这项提议时,Andrei Alexandrescu参加了会议,提供了解释他自己基于policy-based设计的Loki SmartPtr [5] 。SmartPtr提供了四个Boost指针功能的超集。它留下来只是看哪个提议会最终被采纳,但是这些选择很重要。
如果你对Boost、shared_ptr一无所知。如果你曾想得到一个指针容器,只是因为你不能将auto_ptr放进容器(不应该,最好不要编译,如果编译了不管你知道与否,你正裸行在一个雷区[8]),这时它就显得很有价值。你几乎总是想得到的就是shared_ptr容器。shared_ptr 限定于 std::less,另外特别的为这种用法设计的。
随机数[9]
由于自己对密码学感兴趣,至于好的随机数,我有点心虚(我心中有个弱点)。随机数在任何时候任何事情上都用的到,从不重要的,比如棋盘游戏的骰子滚动,到重要的建模应用如生成证券市场模拟的随机输入,到重大的至关紧要的,容易出错的安全应用,比如创建密码安全密钥生成的无法猜测的输入。这些类型的随机数生成有不同的要求;比如有些需要平坦分布(你通常想要骰子每个结果具有1/6的机会,而不是灌铅骰子),有些不需要平坦分布(比如常态分布或泊松分布)
个人认为在标准里加入好的RNG功能很重要,这样开发者将不再倾向于自己设计,而且可能出错。特别是因为C在其标准库里提供了rand函数,大多数时间,开发者过于依赖它;我们在C++中提供rand,是因为要支持C标准库,我个人感觉我们有责任做的更好。现在有过多经常的误解和更多的是给别人一种安全的错觉。
有理数[10]
有理数?,一个标准化的功能提供像:rational<float>(1,10)这样的表达准确表示1/10(你不能作这样的二进制浮点运算),辅助功能如:gcd计算最大公约数。rational_cast模板显式的将有理数转换近似的浮点数,比如rational_cast<double>( r )。
线程[11]
“为什么C++没有线程?”是经常听到的一句话。我们当中的许多人一个星期的每一天都在写多线程程序,但是确实C++标准在线程这个主题上保持沉默,没有提供处理它们的功能(包括的问题像在出现竞争条件下静态对象的初始化,如果你不小心,很容易意外的将他们重复初始化)。
这是事实上的假设下一版C++标注将包括线程支持。在标准库中的准确的形式、要求作多少改变,这些还要等着瞧。对这领域的兴趣和压抑的要求使得Boost线程库可能成为最有趣的提案。这个线程库实现了在UNIX和Windows平台上使用POSIX,在windows平台上也使用本地Win32线程。
[总结]
任何一个功能都没有作最后决定,存在它们的许多竞争版本。委员会欢迎这些和将来的其他提案。其间,我们已经看到在C99兼容(头文件<cstdint>)方面的具体有用的提议、缺陷的填补(智能指针)和特别是在系统编程和泛型编程方面有用的功能(type traits,正则表达式,随机数,有理数和线程)。
下次将会更近的了解上述的提议功能。另外到时候还包括2002年4月将要在Curaçao召开的标准大会的新闻。请等待。
[参考资料]
[1] H. Sutter. "The New C++," C/C++ Users Journal Experts Forum, February 2002, <www.cuj.com/experts/2002/sutter.htm>.
[2] <www.boost.org>
[3] <www.boost.org/libs/integer/cstdint.htm>
[4] <www.boost.org/libs/type_traits/index.htm>
[5] A. Alexandrescu. Modern C++ Design (Addison-Wesley, 2001).
[6] <www.boost.org/libs/regex/index.htm>
[7] <www.boost.org/libs/smart_ptr/index.htm>
[8] H. Sutter. Exceptional C++, Item 37 (Addison-Wesley, 2000).
[9] <www.boost.org/libs/random/index.html>