科技行者

行者学院 转型私董会 科技行者专题报道 网红大战科技行者

知识库

知识库 安全导航

至顶网软件频道基础软件Visual C++的模板和泛型如何配合使用

Visual C++的模板和泛型如何配合使用

  • 扫一扫
    分享文章到微信

  • 扫一扫
    关注官方公众号
    至顶头条

我将演示模板和泛型在何种情况下能配合使用,在何种情况下不能配合使用,并指明在 Visual C++® 2005 下当前模板实现方式的缺陷,以此来结束这一系列有关在 Microsoft® .NET Framework 中进行泛型编程的专栏。

作者:Stanley 来源:msdn中国 2007年11月19日

关键字: Visual C++ 模版 泛型 配合使用

  • 评论
  • 分享微博
  • 分享邮件
我将演示模板和泛型在何种情况下能配合使用,在何种情况下不能配合使用,并指明在 Visual C++® 2005  下当前模板实现方式的缺陷,以此来结束这一系列有关在 Microsoft® .NET Framework 中进行泛型编程的专栏。我选择通过讨论将标准模板库 (STL) 引入 .NET 的过程中进行的工作,来介绍这份材料。首先,我将回顾 STL 的基本元素,这样所有人都将站在同一起跑线上。

  STL 的 CAI

  有三个主要元素可用于标准模板库的设计:容器、算法和迭代器 (CAI)。STL 矢量和 List 类表示顺序容器。顺序容器保存第一个元素、第二个元素等等,直到最后一个元素。用程序来表示的函数参数列表通常作为包含字符串类型的元素的矢量来实现。例如:

以下是引用片段:
  vector paramlist;

  Map 和 Set 类表示关联容器。关联容器支持快速查找。例如,Map 表示键/值对:键用于查找,而值表示存储和检索的数据。要表示电话号码簿,您需要声明一个带有字符串键和整数值的 Map:

以下是引用片段:
  map phonedir;

  多重映射可使单一键支持多个电话条目。

  STL 还提供一个算法集,其中包含用于查找、排序、替换和合并的算法(可以对容器进行运算)。这些算法称为泛型算法,因为它们独立于正在其上进行运算的元素类型(例如整型、双精度类型或字符串类型)和包含元素的容器类型(例如无论容器是矢量、列表还是内置数组)。

  泛型算法通过直接在容器上进行运算来实现容器独立性。程序不向算法传递容器,而是向它们传递标记了要通过其进行迭代的元素范围的迭代器对 (第一个, 最后一个],其中最后一个元素充当终结标志或一个标记,以表明元素集之后的元素并将停止算法:

以下是引用片段:
  sort( paramlist.begin(), paramlist.end() );

  此处,begin() 和 end() 是所有 STL 容器提供的方法,会将迭代器返回到元素集第一个元素和位于末尾元素之后的元素。例如,看一下以下声明序列:

以下是引用片段:
  void f()
  {
  int ia[4] = {21, 8, 5, 13 };
  vector ivec( ia, ia+4 ); //将 ivec 初始化为 ia...(请注意:示例程序文件中的程序员注释使用的是英文,本文中将其译为中文是为了便于参考)
  list ilist( ia, ia+4); //将 ilist 初始化为 ia ...
  // ...
  }

  注意:ia+4 实际指向最后一个元素 (13) 之后的地址。使用 STL 的人们最初可能被这种区别所蒙蔽,例如,传递截止到 ia+3 处,这将使元素 13 不能包括在一系列值中。

  迭代器提供了一种统一且独立于类型的方式来访问、遍历和比较容器的元素。迭代器是一种类抽象,可以提供统一的指针操作(例如 ++、--、*、==、!=),无论容器是内置数组、列表还是其他任何一致的 STL 容器:

以下是引用片段:
  void f()
  {
  // ... 同上...
  // 每次调用相同的泛型算法...
  sort( ia, ia+4 );
  sort( ivec.begin(), ivec.end() );
  sort( ilist.begin(), ilist.end() );
  }

  在每个排序调用中(共三个),结果序列理所当然是:5、8、13、21(Fibonacci 序列的第四个到第七个元素)。

  现在,这只是一种对 STL 的理想化观点,并不能证明在正式约束和实际约束下实际可行。正式约束是指:不是所有的容器类型均支持所有算法运算。例如,Map 或 Set 不支持 random_shuffle,因为对元素进行的任何重新排序均违反容器类型,这就像将索引编入堆栈中将违反堆栈的语义特征一样。

  更实际地说,通过泛型算法,使用排序或查找来获得 List 容器中的元素,比在矢量上进行同一运算更加费力。因此,List 容器类型提供了自己的比泛型算法更高效的类方法。同样,使用 List 容器类型的查找方法来查找 Map 元素,比使用查找算法(通过向算法传递 Map 的开始和结束迭代器及其键)更快捷。

  大家可能会希望算法在所有容器上的执行效果都相同,但实际上,算法更适合在 Block 容器和内置数组,而不是在 List 容器和关联容器类型上使用。实际上,当我在 Bell 实验室与 Alex Stepanov 一起工作时,他就把泛型算法称为 Block 算法。

  为 .NET 重新设计 STL

  要将 STL 合并到 .NET 中,首先要将容器作为公共语言运行库 (CLR) 类型重新实现。出于多种原因,我在本文中不会进行深入的讨论。总之,最好使容器成为引用类而不是值类。例如:

以下是引用片段:
  // 暂时简化声明...
  template 
  ref class vector { ... };
  template 
  ref class map { ... };

  在本机 STL 中,所有容器都是非多态的。矢量的声明将给定实际矢量对象。示例如下:

以下是引用片段:
  // 本机 STL 矢量
  // ivec.empty() == true
  // ivec.size() == 0
  vector< int > ivec;
  // ivec2.empty() == false
  // ivec2.size() == 10
  vector< int > ivec2( 10 );

    • 评论
    • 分享微博
    • 分享邮件
    邮件订阅

    如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。

    重磅专题
    往期文章
    最新文章