【问题标题】:Templates instantiation in C++C++ 中的模板实例化
【发布时间】:2011-09-20 11:26:00
【问题描述】:

我对 C++ 如何实例化模板感到困惑。我有一段代码:

template <class T, int arraySize>
void test1(T (&array)[arraySize])
{
    cout << typeid(T).name() << endl;
}

template<class T>
void test2(T &array)
{
    cout << typeid(T).name() << endl;
}

int main()
{
    int abc[5];
    test1(abc);
    test2(abc);
    return 0;
}

这是我的问题:
1.数组 abc 的大小如何传递给 test1 (参数 arraySize )?
2. C++编译器如何判断两个模板中T的类型?

【问题讨论】:

  • 你的意思是test1&lt;int, 5&gt;(abc)?第二个完全没有意义。你有一个函数test2&lt;T&gt; 并且你正在索引它,就好像它是一个数组一样?!

标签: c++ arrays templates


【解决方案1】:
  1. 没有正常意义上的参数传递,因为模板参数是在编译时解析的。
  2. arraySizeT 都是从array 参数的类型推断出来的。由于您在编译时传递了 int[5]arraySizeT 分别变为 5int

例如,如果您声明了int* abc = new int[5];,您的编译器会在您尝试调用test1(abc) 时出错。除了基本的类型不匹配之外,int* 没有携带足够的信息来推断数组的大小。

【讨论】:

    【解决方案2】:

    叫做模板参数推导

    调用点abc类型是:int(&amp;)[5],它结合了两个信息:int5。并且函数模板接受T(&amp;)[N] 类型的参数,但调用点的参数是int(&amp;)[5],因此编译器推断TintN5

    阅读这些:

    【讨论】:

      【解决方案3】:

      在 test1 中,编译器创建一个模板,其形式为 T[arraySize]。 当您调用 test1(abc) 时,您提供的是模板匹配器自动匹配的 int[5] 类型的输入参数。

      但是,如果你要写

      int n=10;
      int *abc = new int[n];
      test1(abc);
      test1<int,n>(abc);
      

      然后编译将失败,编译器会声称它没有与 test1(abc) 函数调用或 test1(abc) 函数调用匹配的模板。

      这是因为 abc 的大小现在是动态分配的,因此 abc 的类型是一个具有不同类型的指针,因此没有模板可以匹配上述两个调用。

      以下代码向您展示了一些类型

      #include <iostream>
      using namespace std;
      
      template <class T> void printName() {cout<<typeid(T).name()<<endl;}
      
      int main()
      {      
          printName<int[2]>();  //type = A2_i
          printName<int*>();     //type = Pi
      
          getchar();
          return 0;
      }
      

      【讨论】:

      • 此外,abc[n] 无论如何都不会编译,因为 C++ 不支持动态大小的数组(据我所知,甚至 C++11 也不支持)。我猜你有 C99 背景?
      • 它在苹果 llvm 编译器 3.0 下编译得很好。已更新答案。感谢您指出这一点。
      【解决方案4】:

      我还要补充一下 Nawaz 所说的:理论是type inference

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2012-03-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多