C++中的模板实例化

8

我对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 的类型?


1
你的意思是像这样 test1<int, 5>(abc) 吗?第二个根本没有意义。你有一个函数 test2<T>,你却像访问数组一样对它进行索引操作?! - Shahbaz
4个回答

7
  1. 在正常情况下不存在参数传递,因为模板参数是在编译时解析的。
  2. arraySizeT都从array参数的类型中推断出来。由于你传递了一个int[5],所以arraySizeT在编译时分别变为5int

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


5
它被称为“模板参数推导”。
在调用时,abc类型是:int(&)[5],其中包含两个信息: int5。函数模板接受类型为 T(&)[N] 的参数,但调用时的参数是 int(&)[5],因此编译器推断出 TintN5
阅读以下内容:

4

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

然而,如果您写成:

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

如果这样编译,编译会失败,并且编译器会报告没有与test1(abc)函数调用或test1<int,n>(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;
}

1
此外,abc[n]无论如何都不会编译通过,因为C++不支持动态大小的数组(就我所知,即使是C++11也不支持)。我猜你有C99的背景? - Christian Rau
它在苹果的LLVM编译器3.0下编译得很好。已经更新了答案。感谢指出这一点。 - twerdster

0
我还想补充一下Nawaz所说的:这个理论是类型推断

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接