c++ - 模板函数的歧义递归定义

标签 c++ templates

我正在建立一个静态类型的矩阵,其中所有与矩阵的操作都经过类型检查。但是,当我想做一些基于给定数字修改矩阵的问题时,我遇到了问题。

例如,添加一列很简单:

template<int A, int B>
Matrix<A,B+1> addOneCol(Matrix<A,B> m1) {
    return Matrix<A,B+1>();
}

但是,添加N列要困难得多。由于不可能使用具有分支的函数进行类型检查,而分支的返回类型不是预期的(即使分支条件可以保证),所以我只能考虑一种递归方法:
template<int A, int B, int Z>
Matrix<A,B+1> addZCols(Matrix<A,B> m1) {
    return addOneCol(m1);
}

template<int A, int B, int Z>
Matrix<A,B+Z> addZCols(Matrix<A,B> m1) {
    return addOneCol(addZCols<A,B,Z-1>(m1));
}

template<int A, int B>
Matrix<A,B+1> addOneCol(Matrix<A,B> m1) {
    return Matrix<A,B+1>();
}

但是,这会使返回类型中的addZCols重载,这是不允许的,并导致错误,导致调用addZCalls模棱两可,并且无法选择2个候选者之一。我想要的是B+1的版本仅作为基本案例,可以说是Z=1

关于如何进行这项工作或采用其他方法的想法吗?

最佳答案

可能有一种更有效的方法,但是使用您提出的递归解决方案,SFINAE可用于消除模板功能的两个版本的歧义。

#include <type_traits>

template <int A, int B>
struct Matrix {
    constexpr int rows() const { return A; }
    constexpr int cols() const { return B; }

    int data;
};

template<int Z, int A, int B, std::enable_if_t<Z == 0, int> = 0>
Matrix<A, B> addZCols(Matrix<A,B> m1) {
    return m1;
}

template<int Z, int A, int B, std::enable_if_t<Z != 0, int> = 0>
Matrix<A,B+Z> addZCols(Matrix<A,B> m1) {
    return addOneCol(addZCols<Z-1, A, B>(m1));
}

template<int A, int B>
Matrix<A,B+1> addOneCol(Matrix<A,B> m1) {
    return Matrix<A,B+1>();
}

int main() {
    Matrix<2, 2> m1;
    auto m2 = addZCols<3>(m1);

    static_assert(m2.rows() == 2, "check rows");
    static_assert(m2.cols() == 5, "check cols");

    return 0;
}

为了清楚起见,我也将递归限制偏移了一个,并对addZCols的模板参数进行了重新排序以使其调用起来更好,但是它与原始签名的作用相同。

关于c++ - 模板函数的歧义递归定义,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61392024/

相关文章:

c++ - 使用节点的深度复制和解构器哨兵链表

c++ - 如何为模板变量赋予随机值?

c++ - g++ 使用模板时出现重复符号错误(菜鸟问题)

c++ - 奇怪的模板构造函数语法

c++ - 您如何比较两个未知数以查看它们在特例模板中是否相等?

c++ - 简化和重写我的代码

C++类成员函数不修改成员

c++ - 检查函数是否在解决方案中被调用

派生类中的C++成员函数模板,如何从基类中调用它?

javascript - 处理不同模板之间的事件