`
fujinbing
  • 浏览: 237236 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

c++无类型参数模板(non-type template parameter) 与 无具名空间 static

    博客分类:
  • c++
 
阅读更多

     无类型的模板参数:

     C++的template可以传入普通的参数,和平时使用普通的函数参数有点相似,但又有很大的不同。
    这种形式的模板一般是用来初始化类的数组成员的大小例如下面有的代码:


     template<int size>
     class CTest {
         int m_data[size];
     };
    void main() {
        CTest<10> obj;// 将obj对象的成员 数值m_data大小初始为10 ,是不是很简单?
     }


     用整型来作为无类型模板参数使用起来确实simple,那么换其他类型试试?

    
收集了一点资料稍微整理了下,看看下面资料怎么说的:
      a non-type template-parameter shall have one of the following types

      (无类型模板参数应该是下面所列举的类型):
     1. integral or enumeration type(整型 或者 枚举)
     2. pointer to object or pointer to function(对象的指针或函数指针,其实还包括基本类型的指针)
     3. reference to object or reference to function(对象的引用或者函数的引用)
     4. Attention :The C++ standard does not allow floating point non-type template parameters
   (注意:c++标准规定浮点型不能作为无类型模板的参数,但他们的引用和指针是允许的。例如 float,double)


   你已经知道了应该传入什么类型参数,说真的,这还远远不够。
   a template-argument for a non-type, non-type template-parameter shall be one of:
     1.对于整型参数:应该传入一个常量或者枚举值
       an integral constant-expression of integral or enumeration type
     2.对象的指针或者函数的地址因该具有外部连接属性,具有内部链接属性将报错;

       the address of an object or function with external linkage
     3.可以是一个引用类型的参数参数 例如: template<int&> void func() {}; 
       the corresponding template-parameter is a reference

 

     下面再来看看non-type template-parameter 有关的错误描述:
      error c2970: 
      an expression involving objects with internal linkage cannot be used as a non-type argument

     (涉及到对象内部连接的表达式不能作为 non-type argument)

      error c2975:
      expected compile-time constant expression

      (需要一个编译期常量表达式)

      error c2971:
      a local variable cannot be used as a non-type argument,

      You cannot use the name or address of a local variable as a template argument.

    (局部变量不能作为non-type argument,

        这里主要是指:指针和引用,但是局部整型常量除外,所以下面的代码是ok的。

 

 

  1. template<int>  
  2. void fun1()     {}  
  3.       
  4. template<int*>  
  5. void fun1_1()   {}  
  6.   
  7. template<int&>  
  8. void fun1_2()   {}  
  9.   
  10. template<char*>  
  11. void fun2()     {}  
  12.   
  13. template<char>  
  14. void fun3()     {}  
  15.   
  16. struct  CA  {};  
  17. union   Ua  {};  
  18.   
  19. // 浮点数 例如float,double,是不能作为 non-type template parameter的  
  20. //template<float>  
  21. //void fun4()   {}  
  22.   
  23. // 要使用类的或者联合的指针 或者引用  
  24. //template<CA>              
  25. //void fun4()   {}  
  26.   
  27. //template<Ua>  
  28. //void fun5()   {}  
  29.   
  30. template<CA*>           
  31. void fun4_1()   {}  
  32.   
  33. template<CA&>           
  34. void fun4_2()   {}  
  35.   
  36. template<Ua*>  
  37. void fun5_1()   {}  
  38.   
  39. template<Ua&>  
  40. void fun5_2()   {}  
  41.   
  42. //------------------------------------------------------------------------//  
  43. int         idata3 = 20;        // 外部链接  
  44. const int   idata2 = 9;         // 内部链接  
  45.   
  46. CA          impCa1;             // 外部链接  
  47. const CA    impCa2;             // 内部链接  
  48. static CA   impCa3;             // 内部链接  
  49.   
  50. Ua          impUa1;             // 外部链接  
  51. const Ua    impUa2;             // 内部链接  
  52. static Ua   impUa3;             // 内部链接  
  53.   
  54. const char  str3[] = "str";     // 内部链接  
  55. static char str4[] = "str";     // 内部链接  
  56. char        str5[] = "str";     // 外部链接  
  57.   
  58. char*       str6   = "str";     // 外部链接  
  59. const char* str7   = "str";     // 内部链接  
  60. charconst str8   = "str";     // 内部链接  
  61. const charconst str9   = "str";   // 内部链接  
  62.   
  63. const char  chr    = 'x';       // 内部链接  
  64. void funtest(int);  
  65. void funtest( int )     {}  
  66.   
  67. static void funtest2(int);  
  68. void funtest2( int )    {}  
  69.   
  70. typedef void (*ptr_func)(int);  
  71.   
  72. template<ptr_func>  
  73. void fun6()     {}  
  74.   
  75. ptr_func pfun2 = &funtest;  
  76. const ptr_func pfun3 = &funtest;  
  77. static const ptr_func pfun4 = &funtest;  
  78.   
  79.   
  80. int _tmain(int argc, _TCHAR* argv[])  
  81. {  
  82.   
  83.     int i = 12;  
  84.     //const int idata = i;  // error 2971 局部变量不能用作非类型参数  
  85.     const int idata = 10;   // 局部常量 ok  
  86.     fun1<idata>();            // ok  
  87.       
  88.     int idata4 = 20;  
  89.     //fun1_1<&idata2>();  // error c2970 涉及到对象内部连接的表达式不能作为 non-type argument.  
  90.     //fun1_1<&idata4>();  // error c2971   
  91.     fun1_1<&idata3>();        // ok  
  92.       
  93.     //fun1_2<idata2>();       // error c2970  
  94.     //fun1_2<idata4>();       // error c2971   
  95.     fun1_2<idata3>();     // ok  
  96.       
  97.     char        str1[]  = "string";  
  98.     const char* str2    = "string";  
  99.     //fun2<str1>();           // error c2971  
  100.     //fun2<str2>();           // error c2971  
  101.     //fun2<str3>();           // error c2970   
  102.     //fun2<str4>();           // error c2970  
  103.     //fun2<"test">();     // error c2762 模板参数的表达式无效,为什么会无效?字符串"test"具有内部链接? 问题1。  
  104.     fun2<str5>();         // ok  
  105.     //fun2<str6>();           // error 2975 需要一个编译期常量表达式  
  106.     //fun2<str7>();           // error 2975  
  107.     //fun2<str8>();           // error c2971  
  108.     //fun2<str9>();           // error c2971  
  109.   
  110.     //fun3<str2[1]>();        // error 2975 需要一个编译期常量表达式  
  111.     //fun3<str3[0]>();        // error 2975 为什么str3[0]不是编译期常量,问题2  
  112.     fun3<'x'>();          // ok  
  113.     fun3<chr>();          // ok  
  114.   
  115.     // ok  
  116.     fun4_1<&impCa1>();  
  117.     fun4_2<impCa1>();  
  118.   
  119.     // ok  
  120.     fun5_1<&impUa1>();  
  121.     fun5_2<impUa1>();  
  122.   
  123.     //  
  124.     ptr_func pfun = &funtest;  
  125.     //fun6<pfun>();       // error c2971  
  126.     //fun6<pfun2>();  // error c2975  
  127.     //fun6<pfun3>();  // error C2970  
  128.     //fun6<&pfun4>(); // error C2970  
  129.     fun6<&funtest>(); // ok  
  130.     fun6<&funtest2>();  
  131.   
  132.         return 0; 

 

记得以前一个同事问我为什么程序里使用了 anonymouse namespace ,想了想 就回答说其实就是保持局部性(这也是我的目的),然后就有人说为什么不用static,嗯 似乎这两个东西乍一看没什么区别,自己便Google了一下,发现有一个原因就是 anonymousenamespace 里的 member 都是有外部链接的,只不过永远都不能被外部link到!而 static 就明确为根本没有外部链接!此时就出现问题了,在模板里无类型的参数必须是有外部链接的才可以,否则编译无法通;比如:
template <void fn()>
class Foobar
{};

namespace
{
void abc()
{
wcout<<_T(”abc”)<<endl;
};
}
static void efg()
{
wcout<<_T(”efg”)<<endl;
};
int _tmain(int argc, _TCHAR* argv[])
{
Foobar<abc>xyz //! ;这一行可以通过
Foobar<efg>rst; //! 注意这一行编译不过
return 0;
}
也有人认为使用 anon namespace比较好,因为static的方式被C++98标准所批评,呵呵 总体来说 ,其实你完全可以用anony namespace代替static

 

分享到:
评论

相关推荐

    深入理解C++11-C++11新特性解析与应用

    深入理解C++11-C++11新特性解析与应用, 文件小而清晰,

    C++ 6.0 Template(模板库)参考手册.zip

    2. 非类型参数(Non-Type Parameter):可以是整型、指针或枚举类型,它们在模板实例化时必须提供具体的值。 三、模板特化(Template Specialization) 当通用模板不能满足特定需求时,可以对模板进行特化,创建...

    C++模板中文 PDF 版 不错的c++模板书籍

    2. **模板参数**:讲解模板参数的不同类型,如类型参数(Type Parameter)和非类型参数(Non-Type Parameter),以及它们在实例化模板时的作用。 3. **模板实例化**:讨论如何实例化模板,包括显式实例化、隐式实例...

    一个c++ 参数模版映射的例子

    这些参数可以是类型参数(Type Parameter)或非类型参数(Non-Type Parameter)。类型参数用`typename`或`class`关键字声明,用于代表任意数据类型。例如: ```cpp template void print(T value) { std::cout ; }...

    c++系列-泛型编程与模板-源码

    模板函数是C++中的泛型函数,它通过参数化类型来实现。例如,下面是一个简单的模板函数,用于交换两个变量的值: ```cpp template void swap(T& a, T& b) { T temp = a; a = b; b = temp; } ``` 在这个例子中...

    NLM(non-local means)c源码,降噪算法

    NLM, non-local means c源码,降噪算法,效果出众

    C++Templates_c++templates_C++Templates全览_healthbhr_源码.rar

    - **非类型参数(Non-Type Parameter)**:非类型参数可以是整型、指针或枚举值,它们在模板实例化时必须提供具体值,如`template&lt;int N&gt; void printArray() {}`。 3. **模板特化(Template Specialization)** -...

    c++template 模板介绍

    C++中的模板(Template)是其泛型编程的基础,它允许程序员编写不依赖于特定数据类型的函数或类。模板提供了一种方式来实现通用的代码,这样就可以在各种数据类型上重用相同的逻辑,而无需为每种类型分别编写代码。 ...

    The Annotated C++ Reference Manual(ARM)-Ch07

    这部分内容主要围绕“声明”(Declarations)展开,因此我们将重点关注C++中的声明规则、语法以及与之相关的特性。 ### 第七章:声明 (Declarations) #### 1. 声明的基本概念 在C++编程语言中,**声明**是告诉...

    C++Template电子书及代码

    这份"C++Template电子书及代码"资源为学习C++模板提供了宝贵的材料,下面我们将深入探讨C++模板的基础知识、应用场景以及一些高级特性。 1. 模板基础: - 函数模板:C++函数模板允许我们创建不依赖于特定数据类型...

    c++模板经典书籍

    在"两本很好的讲解c++ template的书"中,我们可以期待深入理解模板的各个方面,包括基本概念、特性和最佳实践。 首先,模板分为两种类型:函数模板和类模板。函数模板用于定义通用函数,如`std::swap`,可以接受...

    《 C++模板》和《C++模板元编程》两本

    C++模板是C++语言中的一个强大特性,它允许程序员创建泛型代码,即能够处理多种数据类型的代码。模板在C++中分为两种主要类型:函数模板和类模板。函数模板用于定义可以接受不同类型参数的函数,而类模板用于创建...

    C++模板中文版及源代码

    - 成员函数通常也是模板,可以与模板参数一起进行类型推断。 3. **模板特化**: - 当我们想要为特定类型提供不同的实现时,可以进行模板特化。这在标准库中常见,比如为`std::pair`的`int, int`版本优化。 - ...

    The Annotated C++ Reference Manual(ARM)-Ch17

    - **模板参数**(Template Parameters):模板参数可以是类型、非类型(整型、浮点型等)或者模板模板参数。 - **模板特化**(Template Specialization):允许对特定类型或类型组合提供不同的模板实现。 - **模板元...

    C++ Templates

    - **非类型参数(Non-Type Parameter)**:非类型参数是除了类型外的其他参数,通常是常量表达式,如整型、指针等。 3. **模板实例化(Template Instantiation)** - 当我们使用模板定义的函数或类时,编译器会...

    C++ template 中文版

    C++模板是C++语言中的一个强大特性,它允许程序员创建泛型代码,即能够处理多种数据类型的代码。模板在C++中分为两种主要类型:函数模板和类模板。候捷先生的《C++模板》中文版是一本深入探讨这个主题的教材,非常...

    C++ Template

    C++ 模板是C++编程语言中的一个强大特性,它允许程序员定义泛型代码,即可以在多种数据类型上工作的代码。模板分为两种主要类型:函数模板和类模板。本篇将深入探讨C++模板的基本概念、使用方法以及在实际编程中的...

Global site tag (gtag.js) - Google Analytics