设为首页 加入收藏

TOP

C++模板的特化(四)
2013-04-24 12:13:11 来源: 作者: 【 】 浏览:735
Tags:模板

 

  再谈谈函数模板参数的推导,大致有以下几种方法,但是不管怎么推导,都必须得保证在调用函数前能确定模板函数的各个模板参数的类型。

  template <typename T1, typename T2>

  T2 fun(T1 arg1, int arg2)

  {

  T2 t2;

  return t2;

  }

  对于上面这种比较特殊的模板函数,你不能通过传递参数来自动得到所有模板参数的类型,因此你必须显示的指定T1和T2的类型,有两种方法可以实现此目的:

  int (*pfun)(double,int) = fun;//借用函数指针定义

  cout《pfun(12.2,11)《endl;

  cout《fun<int,double>(11, 3.2)《endl;//直接指定类型

  如果上述模板函数改为:

  template <typename T1, typename T2>

  T2 fun(T1 arg1, T2 arg2)

  {

  return arg2;

  }

  那么除了上述两种指定模板参数类型的方法之外,由于该模板函数参数的类型都可以借由其参数获得,因此我们省去指定模板参数这一步骤,而直接调用该模板函数:

  fun(23, 2.3);

  最后,再谈谈非类型模板参数的问题,在《C++(www.cppentry.com) Template》的第四章有介绍。

  template<typename T, int LEN> struct stack {…};

  template<int margin> int add(int x){return x+margin;}

  上面两个例子分别对应了类和函数两种情形,有人说非类型的模板参数存在得毫无价值,实则不然,因为我们可以借由一个确定的数值来产生一种新的类型或者新的函数。对于上面两个例子,我觉得用非类型模板参数就很有意义,分别实现了让用户指定stack的大小以及指定需要增加的边际值,关于更多这方面的应用,大家可以在今后的开发过程中逐步发掘,此外,还很有必要强调一下对非类型模板参数的限制,不能使用浮点数、class类型的对象和内部链接对象(例如字符串常量"hello world!")作为实参;它们可以是常整数(包括枚举值)或者指向外部链接对象的指针。

  对外部链接对象的指针举个例子:

  template <char const* name>

  class MyClass {…};

  extern char const s[] = "hello";

  MyClass<s> x;       //OK

  好了,模板这块内容我先将这么多。

  又从网上搞到点好东东,也贴在这里吧:

  类模板:

  * 如果类模板中含有静态成员,那么用来实例化的每种类型,都会实例化这些静态成员。

  * 两个靠在一起的模板尖括号( > ) 之间需要留个空格,否则,编译器将会认为是在使用operator》,导致语法错误。

  * 特化的实现可以和基本类模板的实现完全不同。

  * 类模板可以为模板参数定义缺省值,称为缺省模板实参,并且他们还可以引用之前的模板参数。

  * 成员函数模版不能被声明为虚函数。

  * 类模板不能和另外一个实体共享一个名称。

  eg:

  1         int C;

  2

  3         class C;    // ok,

  4

  5         int X;

  6

  7         template < typename T >

  8

  9         class X;    // error. 和变量X冲突

  非类型模板参数:

  在编译期或链接期可以确定的常值。这种参数的类型必须是下面的一种:

  a> 整型或枚举

  b> 指针类型( 普通对象的指针,函数指针,成员指针 )

  c> 引用类型( 指向对象或者指向函数的引用 )

  其他的类型目前都不允许作为非类型模板参数使用

  今天又突然挖掘出来点好东东,贴在这里:

  template <typename t>

  void f(t t) {} //f1

  template <>

  void f(int t) {} //f2

  void f(int t) {} //f3

  void f(char t) {} //f4

  f(3); //invoke f3

  f('3'); //invoke f4

  /**

  caveat: f3 must be put after f2, or an error occurs: specialization of void f(T) [with T = int] after instantiation;

  notes: the compiler will use f3 as the instantiation for f1, and use f2 as the specialization for f1;

  rule: specialization must be before instantiation (*);

  Above we have discuss the template function, and then we'll focus on member template function.

  acronym: MTF(member template function);

  Firstly, you should pay attention to the rule: the specialization of MTF must be the outside of the class, i.e., inline should not be allowed.

  Secondly, specialization and instantiation still follow the rule (*)。 But you'd better put the instantiation outside of the class since specialization must be the outside of the class(the root cause is: if you wanna specialize a MTF, you should give compiler the defenition of the templcate firstly. But if you use the specialization as the inline method, the specialization will be anxious since you can put the defination of MTF outside of the class. As you know, the inline member function precedes the non-inline member function. So the compiler will chose the safest way to solve it, i.e., the specialization must be put outside of class declaration)。

  */

        

首页 上一页 1 2 3 4 下一页 尾页 4/4/4
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇Floyd(最短路径问题) 下一篇调试秘笈之运行时的错误

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: