你可以实例化一个模板的非特殊化版本,并在特殊化里面继承它吗?

问题描述 投票:2回答:1

我正在尝试定义一个 Vector 作为行列 Matrix. Vector 需要一些方法 Matrix 没有的,所以我专门 Matrix:

template<typename T, unsigned N, unsigned M>
struct Matrix {
    T data[N][M];
};

template <typename T, unsigned N>
struct Matrix<T, N, 1> : public Matrix<T, N, 1> {
    T at(unsigned index) {
        return data[index][0];
    }
};

template <typename T, unsigned N>
using Vector = Matrix<T, N, 1>;

这段代码不能编译,因为特殊化是一个递归类型。我在这里需要继承的原因是,我可以将所有的内容都包含在 Matrix 到专门化中,而不需要复制&粘贴。

有什么方法可以让我将原来的 Matrix 并从它那里继承?如果有的话,我的类型会不会变成非递归的?

我想到的另一个解决这个问题的方法是简单的 #include 楷体 Matrix 到初始定义和所有的特殊化。但这远远不是习惯性的。

c++ templates matrix specialization
1个回答
1
投票

你可以使用 SFINAE 来禁用方法。需要有模板方法,模板参数依赖于类模板参数。

C++11:

#include <type_traits>

template<typename T, unsigned N, unsigned M=1>
struct Matrix 
{
    T data[N][M];

    template<typename V = T>
    typename std::enable_if<M == 1, V>::type at(unsigned index)
    {
        return data[index][0];
    }
};

template <typename T, unsigned N>
using Vector = Matrix<T, N, 1>;

int main()
{
    Matrix<int, 2, 3> m;
    Vector<int, 5> v;

    // m.at(0); 
    v.at(1);
}

C++14:

#include <type_traits>

template<typename T, unsigned N, unsigned M=1>
struct Matrix 
{
    T data[N][M];

    template<typename V = T>
    std::enable_if_t<M == 1, V> at(unsigned index)
    {
        return data[index][0];
    }
};

template <typename T, unsigned N>
using Vector = Matrix<T, N, 1>;

int main()
{
    Matrix<int, 2, 3> m;
    Vector<int, 5> v;

    // m.at(0); 
    v.at(1);
}

C++20 (感谢Jarod42)。

template<typename T, unsigned N, unsigned M = 1>
struct Matrix 
{
    T data[N][M];

    T at(unsigned index) requires (M == 1)
    {
        return data[index][0];
    }
};

template <typename T, unsigned N>
using Vector = Matrix<T, N, 1>;

int main()
{
    Matrix<int, 2, 3> m;
    Vector<int, 5> v;

    // m.at(0); 
    v.at(1);
}

godbolt


2
投票

下面是一种方法。

template<typename T, unsigned N, unsigned M>
struct Matrix {
    T data[N][M];
};

template<typename T, unsigned N>
struct MatrixTN : Matrix <T, N, 1> {
    T at(unsigned index) {
        return this->data[index][0];
    }
};

template<typename T, unsigned N>
using Vector = MatrixTN <T, N>;

注意: this->data 是需要延迟评估的。data 到第二阶段的模板查询。

现场演示


2
投票

在C++20中,你可以使用 requires 来丢弃方法。

template<typename T, unsigned N, unsigned M>
struct Matrix {
    T data[N][M];

    T at(unsigned index) requires (M == 1) {
        return data[index][0];
    }
};

在以前的标准中,你可能会用SFINAE代替。

© www.soinside.com 2019 - 2024. All rights reserved.