具有void函数的模板特化

时间:2015-11-16 20:40:32

标签: c++

我正在开发一个小程序,我创建了一个2d数组。函数本身工作正常,但是当我想在自己的文件中实现该函数时,我遇到了问题。这就是它的样子:

mat.cpp:

#include <iostream>
#include <iomanip>
#include "matdyn.hpp";

int main(){
    int row, column;
    cin >> row;
    cin >> column;

    int** M1;
    double** M2;

    reserve(M1, row, column);
    reserve(M2, row, column);

    return 0;
}

matdyn.hpp

#ifndef dyn
#define dyn
template <typename T, typename S>
void reserve(S **, T, T);
#endif

matdyn.cpp:

#include "matrix_dyn.hpp"

template <typename S, typename T>
void reserve(S **&x, T row, T column){
    x = new S*[row];
    for(int i = 0; i < row; ++i) {
        x[i] = new S[column];
    }
}  

template void reserve<int, int, int>(int, int, int);
template void reserve<double, int, int>(double, int, int);

我的问题是matdyn.cpp的最后一部分。 我总是得到如下错误消息:

error: template-id ‘reserve<int, int, int>’ for ‘void reserve(int, int, int)’ does not match any template declaration    
template void reserve<int, int, int>(int, int, int);

如何正确编写最后两行?谢谢你的帮助!

3 个答案:

答案 0 :(得分:2)

您的代码存在一些问题:

您的函数reserve定义和声明不匹配。

我相信你想写:

template <typename T, typename S>
void reserve(S **x, T row, T column){

关于显式模板函数即时性,应该这样做:

template void reserve<int, int>(int **, int, int);
template void reserve<int, double>(double **, int, int);

您必须匹配函数声明中给出的模板参数。

这里有live code编译。

答案 1 :(得分:0)

您必须将模板函数的定义放在标题matdyn.hpp

#ifndef dyn
#define dyn
template <typename S, typename T>
void reserve(S **&x, T row, T column){
    x = new S*[row];
    for(int i = 0; i < row; ++i) {
        x[i] = new S[column];
    }
}  

template void reserve<int, int>(int**&, int, int);
                      ^^^^^^^^  ^^^^^^
template void reserve<double, int>(double**&, int, int);
                      ^^^^^^^^^^^  ^^^^^^^^^

#endif

或者在matdyn.hpp中包含matdyn.cpp

#ifndef dyn
#define dyn
template <typename T, typename S>
void reserve(S **, T, T);

#include "matdyn.cpp"

#endif

关于这个SO question

的原因

还要注意模板专业化的错误。函数模板特化的模板参数列表必须与函数模板的模板参数列表匹配。

答案 2 :(得分:0)

引自here

  

模板的定义必须在隐式实例化时可见,这就是模板库通常在标头中提供所有模板定义的原因(例如,大多数升级库只是标题)

因此,您应该将所有内容放在头文件中,因为这是最常用的方法。