调用多参数模板函数

时间:2018-08-14 03:00:44

标签: c++ templates

我试图从我的主体中调用模板化函数。我以前使用过这种语法,其工作方式如下所示:

#include <iostream>

using namespace std;

// One argument in template
template<int size> 

void print(char matrix[][size]) {
    for (int i = 0; i < size; i++) {
        for (int j = 0; j < size; j++) {
            cout << matrix[i][j];
        }
        cout << endl;
    }

    return;
}

// MAIN
int main() {
    constexpr int n = 3;
    char matrix[n][n] = {'a', 'b', 'c',
                         'h', 'i', 'd', 
                         'g', 'f', 'e'};

    print<n>(matrix); // Calling function like this

    return 0;
}

我主要是在尝试使用多参数模板在此应用相同的方法,但是它不起作用。我收到错误消息:没有匹配的函数调用'setRowZero'。我不太了解为什么它不匹配,因为我遵循上面的相同结构。这只是另外一个参数!

#include <iostream>

using namespace std;

template<int num_rows, int num_cols>

// Set this entire row to 0
void setRowZero(int matrix[num_rows][num_cols], int row, int cols) {
    for (int i = 0; i < cols; i++) {
        matrix[row][i] = 0;
    }

    return;
}

int main() {
    // Matrix to be changed
    int matrix[3][4] = {1, 1, 1, 1,
                        1, 0, 1, 1,
                        1, 1, 0, 1};

    // Get row and cols
    int num_rows = sizeof(matrix)/sizeof(matrix[0]);
    int num_cols = sizeof(matrix[0])/sizeof(int);

    // Record the position of the 0s
    for (int i = 0; i < num_rows; i++) { // rows
        for (int j = 0; j < num_cols; j++) { // cols
            if (matrix[i][j] == 0) {
                rows[i] = 0;
                cols[j] = 0;
            }
        }
    }

    // Set to 0's
    for (int i = 0; i < num_rows; i++) {
        if (rows[i] == 0) {
            setRowZero<num_rows, num_cols>(matrix, i, num_cols);
        }
    }

    return 0;
}

2 个答案:

答案 0 :(得分:3)

// Set this entire row to 0
template<int num_rows, int num_cols>
void setRowZero(int (&matrix)[num_rows][num_cols], int row) {
  for (int i = 0; i < num_cols; i++) {
    matrix[row][i] = 0;
  }
}

和致电站点:

setRowZero(matrix, i);
由于C ++中的C兼容性问题,

array参数不是数组。他们“衰减”到指针。

对数组的引用仍然是对数组的引用。

这就是发明std::array的原因;它的病理学表现较差。

答案 1 :(得分:1)

首先,未定义row和cols变量,所以我做了一些虚假的(如果您实际运行它们将崩溃),因为这不是问题的核心部分(它们被注释为“这很糟糕”)

问题是您无法将运行时定义的变量传递给模板。编译器必须在编译时就知道这些值,所以我将它们更改为constexpr,这就是解决您所要问的主要问题的方法。

https://godbolt.org/g/yihHNH

#include <iostream>

using namespace std;

template<int num_rows, int num_cols>
void setRowZero(int matrix[num_rows][num_cols], int row, int cols) {
    for (int i = 0; i < cols; i++) {
        matrix[row][i] = 0;
    }

    return;
}

int main() {
    int * rows; // this is bad
    int * cols; // this is bad
    // Matrix to be changed
    int matrix[3][4] = {1, 1, 1, 1,
                        1, 0, 1, 1,
                        1, 1, 0, 1};

    // Get row and cols
    constexpr int num_rows = sizeof(matrix)/sizeof(matrix[0]);
    constexpr int num_cols = sizeof(matrix[0])/sizeof(int);

    // Record the position of the 0s
    for (int i = 0; i < num_rows; i++) { // rows
        for (int j = 0; j < num_cols; j++) { // cols
            if (matrix[i][j] == 0) {
                rows[i] = 0;
                cols[j] = 0;
            }
        }
    }

    // Set to 0's
    for (int i = 0; i < num_rows; i++) {
        if (rows[i] == 0) {
            setRowZero<num_rows, num_cols>(matrix, i, num_cols);
        }
    }

    return 0;
}

如另一个答案所示,如果不指定num_rows和num_cols,则可以让编译器推断出正确的值。从调用站点上使用的变量类型开始,这样做的目的是,传入的变量类型的维度也是编译时常量。