使用模板C ++对2D数组求和 [英] Summation of 2D arrays using templates C++

查看:67
本文介绍了使用模板C ++对2D数组求和的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我只是在玩模板,我正在尝试添加标题中所述的两个2D数组...请帮助我如何更改我的代码以使其正常工作...代码如下所示.. 。

Hi, i'm just playing around with templates and i'm trying to add two 2D arrays as stated in title...please help how should i change my code to make it work...code shown below...

template <typename Left, typename Right>
class sum
{
private:
    Left *myleft;
    Right *myright;
public:
    sum(Left *l, Right *r) : myleft(l), myright(r) {}

    class Inner
    {
    private:
        Left _myleft;
        Right _myright;
    public:
        Inner(Left l, Right r) : _myleft(l), _myright(r) {}
        double operator[](int j)
        {
            return (_myleft[j]+_myright[j]);
        }
    };

    Inner operator[](int i)
    {
        return Inner(myleft[i]+myright[i]);
    }
};

class array
{
private:
    double** data;
    int N, M;
public:
    array( double **_data, int _N, int _M) :data(_data), N(_N), M(_M) { }

    class Proxy
    {
    private:
        double* _data;
    public:
        Proxy(double* __data) : _data(__data) { }
        double operator[](int j)
        {
            return _data[j];
        }
    };

    template <typename Left,typename Right>
    void operator=(sum<Left,Right> expr)
    {
        for(int i=0; i<N; ++i)
            for(int j=0; i<M; ++j)
                data[i][j] = expr[i][j];
    }

    Proxy operator[](int i)
    {
        return Proxy(data[i]);
    }
};

template <typename Left>
sum<Left, array> operator+( Left a, array b)
{
    return sum<Left, array>(a,b);
}

int main()
{
    double **test;
    test = new double*[5];
    for(int i=0; i<5; ++i){
        test[i] = new double[4];
        for(int j=0; j<4; ++j){
            test[i][j] = 1.0;
        }
    }

    array a(test,5,4), b(test,5,4), c(test,5,4);

    c = sum<array,array>(a,b);  // <<----error here

    for(int i=0; i<5; ++i){
        cout<<"\n";
        for(int j=0; j<4; ++j){
            cout<<c[i][j]<<" ";
        }
    }
}

推荐答案

我不会使用指向元素的指针而是定义矩阵使用数字模板参数。例如。
I would not use pointers to elements but rather define the Matrix using numeric template parameters. E.g.
template<typename TElem, size_t R, size_t C=R>
class Matrix
{
  ...
};

然后在内部定义类一些类型和数据存储,例如

Then define internally to that class some types and the data storage, e.g.

...
public:
  typedef TElem ElementType;
  typedef ElementType RowType[C];
  typedef RowType MatrixType[R];
private:
  MatrixType _matrix;
...

后面是该类的一些构造函数,例如

Followed by some constructors for that class, e.g.

...
public:
  Matrix()
  {
    for(size_t i = 0; i < R; ++i) for(int j = 0; j < C; ++j) _matrix[i][j] = 0;
  }
  Matrix(const MatrixType &matrix)
  {
    for(size_t i = 0; i < R; ++i) for(int j = 0; j < C; ++j) _matrix[i][j] = matrix[i][j];
  }
...

最后实现该类中的添加和一些打印工具,例如

Finally implement the adding and some print facility within that class, e.g.

 ...
Matrix& addAssign(const Matrix& rhs)
{
  for(size_t i = 0; i < R; ++i) for(int j = 0; j < C; ++j) _matrix[i][j] += rhs._matrix[i][j];
  return *this;
}

void print(ostream& out, const string& name) const
{
  out << "### " << name << " ###" << endl;
  for(size_t i = 0; i < R; ++i)
  {
    for(int j = 0; j < C; ++j)
    {
      if (j > 0) out << ",";
      out << _matrix[i][j];
    }
    out << endl;
  }
}
...

请注意,我实施了就地添加,即通过添加 rhs 元素到自己的元素。



使用:

Note that I implemented in-place adding, i.e. the matrix gets modified by adding the rhs elements to the own elements.

Using:

typedef Matrix<double,2,3> M23;
M23 a;
M23 b(a);
M23::MatrixType m = {{1,0,0},{0,1,0}};
M23 c(m);
a.print(cout, "a");
b.print(cout, "b");
c.print(cout, "c");
c.addAssign(c);
c.print(cout, "c");



结果:


Result:

### a ###
0,0,0
0,0,0
### b ###
0,0,0
0,0,0
### c ###
1,0,0
0,1,0
### c ###
2,0,0
0,2,0

干杯

Andi

Cheers
Andi


你有一些问题,一个的构造函数sum 指向正确但是在使用时,指针没有被传递。



我认为如果内部类被分解,问题变得更加简单;

You have a few issues, for one the constructor of sum takes pointers to Left and Right but when used, pointers are not being passed.

I think the problem becomes simpler to look at if the internal classes are broken out;
#include<iostream>

using namespace std;

/* represents a one-dimensional array */
template<typename T> class row {
private:
    T* data;
    size_t n;
public:
    row(T* data, size_t n)
        : data(data), n(n) {
    }

    T operator[](int i) {
        return data[i];
    }
};

/* represents a two-dimensional array */
template<typename T> class array {
private:
    T** data;
    size_t n, m;
public:
    array(T** data, size_t n, size_t m)
        : data(data), n(n), m(m) {
    }

    row<T> operator[](int i) {
        return row<T>(data[i], m);
    }
};

/* represents a two rows from two arrays, observable as a single summed row */
template<typename T> class sum_row_proxy {
private:
    row<T> left;
    row<T> right;
public:
    sum_row_proxy(row<T> left, row<T> right)
        : left(left), right(right) {
    }

    T operator[](int i) {
        return left[i] + right[i];
    }
};

template<typename T> class sum {
private:
    array<T> left;
    array<T> right;
public:
    sum(const array<T>& left, const array<T>& right)
        : left(left), right(right) {
    }

    sum_row_proxy<T> operator[](int i) {
        return sum_row_proxy<T>(left[i], right[i]);
    }
};

int main() {
    double **test = new double*[5];
    for(int i = 0; i < 5; ++i) {
        test[i] = new double[4];
        for(int j = 0; j < 4; ++j) {
            test[i][j] = 1.0;
        }
    }

    array<double> array_a(test, 5, 4);
    array<double> array_b(test, 5, 4);

    sum<double> s(array_a, array_b);

    for(int i=0; i<5; ++i){
        cout<<"\n";
        for(int j=0; j<4; ++j){
            cout<<s[i][j]<<" ";
        }
    }

    return 0;
}







我试过(大致)使用你用的相同课程,但是这个问题也可以通过单个类(加上第二个索引器的代理类)来解决,输入两个 T **



希望这会有所帮助,

Fredrik




I've tried to use (roughly) the same classes you used, but this problem can also be solved by a single class (plus a proxy class for the second indexer) taking two T** as input.

Hope this helps,
Fredrik


我不会声明模板类,而是模板函数。并设计具有三个参数的函数:左操作数,右操作数和结果。如果不使用result参数,则必须将结果作为函数的返回值传递。然而,这不是你想要的。如果返回值也是指向数组的指针,则该函数必须分配该数组。调用代码必须释放数组。



所以:我会选择类似的东西:

I would not declare a template class, but a template function. And would design the function with three arguments for: left operand, right operand, and result. If you don't use a result argument, you will have to pass the result as the return value of your function. That, however, is not what you want. If the return value would also be a pointer to an array, the function would have to allocate that array. And the calling code would have to free the array.

So: I would go for something like:
template<typename t="">
void sum2D (T* pLeft, T* pRight, T* pSum, int cols, int rows)
{
   int n = cols * rows;
   for (int i = 0; i < n; ++i)
      pSum[i] = pLeft[i] + pRight[i};
};
</typename>



请注意,现在调用者必须为结果数组分配空间。


Note that now the caller has to allocate the space for the result array.


这篇关于使用模板C ++对2D数组求和的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆