我的问题肯定很愚蠢,但是在我对C ++ 11和模板编程的理解中有很多漏洞,我不知道该如何解决。

我正在滚动自己的非常简单的线性代数库:

typedef short index_t;

template<int M, int N, typename T = double>
class mat {
    // may want some specialized constructors for mat<1,N,T> and mat<M,1,T>
public:
    T& operator()(index_t i, index_t j) {
        return buf[i + j*M];
    }
    T& operator[](index_t k) { // useful for special cases where matrix is vector
        return buf[k];
    }

    // etc...

private:
    std::array<T, M*N> buf;
}

typedef mat<2, 1, double> col2d;
typedef mat<3, 1, double> col3d;
typedef mat<1, 2, double> row2d;
typedef mat<1, 3, double> row3d;
typedef mat<2, 2, double> mat2d;
typedef mat<3, 3, double> mat3d;


我只希望它支持一种直接分配(或至少初始化)向量(即具有单维度的矩阵)的方法。例如,我希望能够执行v = col2d(v1,v2)或至少执行col2d v = {v1,v2}。我的印象是公开buf可能允许col2d v = {{v1, v2}},但是我不喜欢公开buf的想法。我不希望为每个(1,N)和每个(M,1)编写一个专门的构造函数。我试图使该库尽可能简单易读。

有什么建议吗?

最佳答案

mat(std::array<T, M*N>&& buffin):buf(std::move(buffin)){}
mat(std::array<T, M*N> const& buffin):buf(buffin){}


这不会公开buf,但是会提供col3d x = {{{ 1,2,3 }}};语法。

它还允许使用平面缓冲区初始化Mat 3d。我自己觉得这很有用。

我可能会想添加

struct flat_t{constexpr flat_t(){};};
constexpr flat_t flat{};


然后在array前缀之前加上mat。这样可以防止意外的隐式转换,同时仍允许flat_t样式返回。

另一个是

template<class...Ts,
  std::enavle_if_t< (sizeof...(Ts)==N*M), int> =0
>
mat(flat_t, Ts&&...ts):
  buf{{std::forward<Ts>(ts)....}}
{}


这给你

col2d{flat, 1,2};


作为有效的return {flat, {{1,2,3}}};

添加一条可将所有col2d均可转换为Ts的sfinae测试是此路径的下一步。

10-08 19:53