7.11 将STL容器联合使用

在使用一个同义语词汇编(thesaurus)时,读者可能想知道所有与某个特定单词相似的所有单词。在查寻一个单词的时候,读者希望结果由一个单词表给出。这里,那些“多重”容器(multiset或者multimap)都不适合。解决方案是将容器联合在一起使用,该方法用STL很容易实现。在这里,我们需要一个工具,其结果是形成一个功能强大的通用的概念,那就是能使字符串与一个vector关联成为map:

7.11 将STL容器联合使用 - 图1

7.11 将STL容器联合使用 - 图2

Thesaurus将一个string(即单词)映射到一个vector<string>(同义词)。TEntry是Thesaurus中的一个条目。通过为TEntry创建一个输出流操作符ostream operator<<,可以很容易地打印来自Thesaurus中的这一条目(而整个Thesaurus可以容易地用copy()进行打印)。注意,流插入符所处的非常奇怪的位置:它被放置在std名字空间中![1]上面的这个operator<<()函数将在main()中的第1个copy()调用中被ostream_iterator使用。在编译器实例化时,所需要的ostream_iterator特化根据参数关联查找(argument-dependent lookup, ADL)规则,它只查看std,因为函数copy()所有的参数都在那儿声明。如果在全局名字空间中声明插入符(将其范围限定为迁移名字空间块),它就不会被发现。将其放入std中,就可以通过ADL找到它。

ThesaurusGen创建“单词”(它们仅是单个字母)以及这些单词的“同义词”(这是另外一些随机选择的单个字母)以用作同义语词汇编的条目。它随机挑选制造同义词条目的个数,但必须至少为两个。所有被选择的字母都被编进一个静态字符串static string索引中,该static string是ThesaurusGen的一部分。

在main()函数中,创建一个Thesaurus,并填入10个条目,并且调用copy()算法将它们打印出来。函数menu()要求用户通过键入代表单词的字母来选择一个“单词”来进行查寻。用成员函数find()来查找以确定该条目是否在map中。(记住不要使用operator[],它将会在未找到匹配条目的情况下自动创建一个新的条目!)如果存在,就用operator[]取出vector<string>进行显示。对于reply字符串的选择是随机产生的,允许进行自动测试。

模板的使用使得表达功能强大的概念变得很容易,甚至可以更进一步地扩展这个概念创建一个vector的map,而vector又包含有map等等。由于这个原因,可以用这种方法联合任何STL容器。

[1]从技术上讲,用户向标准名字空间中添加东西是不合法的,但这是防止出现隐藏的名字查找问题的最简单的方法,并且被使用的所有编译器支持。