2016-12-30 127 views
3

我需要使用矩阵,我使用这种声明的,例如用于int数据类型:C++ - 自定义的矩阵结构

std::vector < vector <int>> my2Dvec(rows, vector <int> (cols)); 

但现在我想将它用于多种数据类型,所以我宣布这个模板:

template <typename T> 
struct matrix 
{ 
    int col, row; 
    std::vector <std::vector <T>> data; 

    matrix(int c, int r) : col(c), row(r), data(col, std::vector <T> (row)) 
    { 
     ; 
    } 
}; 

所以我可以用它作为为:

matrix <int> m(10, 10); 
... 
m.data[1][2] = 0; 

现在,我该如何使用(如果可能):

m[i][j] = someValue; 

?如何实现这样的功能?

+0

因为你是新来这个,你可能想通过简化它的() - 运算符,而不是[] - 运算符有两个参数。也就是说,你只需要使用T&operator()(const uint x,const uint y){return data [x] [y];},T operator()(const uint x,const uint y)const {return data [ x] [y];},这导致访问像m(i,j)= someValue ;.可能比代理方法更具可读性。无论如何,你想保护子向量 - m [i] .resize(3)不应该工作。出于这个原因,你可能想把它作为一个类,所有属性都是私有的而不是结构。 – Aziuth

回答

1

你只需要实现一个[]操作返回到行的引用:

std::vector<T> & operator[](int i) { 
    return data[i]; 
} 

由于operator []已经在矢量来定义,这将是足够的。


关于封装的一点。

这可以这样使用,因为它被声明为一个结构体,具有公共实现,这里没有封装。如果matrix隐藏了其实现(这是正常的C++方式),则应该简单地声明一个实现operator []Row<T>类型。这只不过是duck typing,即使它更多地用于Python或Ruby等动态语言,它甚至可以帮助C++。

这是尊重通过鸭子类型封装的例子:

/* 
class Matrix represents a matrix 
operator[](int i) returns a reference to the ith Row 
Row is an internal type that simply defines the operator[](int j) to return 
the ith element in a Row (which is a T&) 
*/ 
template <typename T> 
class Matrix { 
    // implementation 
    int col, row; 
    typedef std::vector<T> Row; 

    std::vector<Row> data; 

public: // interface 
    Matrix(int c, int r): row(r), col(c), data(c, std::vector<T>(r)) {} 

    // allow to use matrix[i][j] 
    Row & operator[](int i) { 
     return data[i]; 
    } 
}; 
+0

您应该指定(在抽象级别上)它只是(部分地)工作,因为它是一个结构体,如果它是一个私有向量的类,它会破坏封装并使用可能链接到实现的运算符创建代码。 –

+0

我同意@ChrisR。来自Serge Ballesta的解决方案并没有以一种很好和方便的方式解决问题。 – paweldac

+0

@ChrisR .:你说得对,这是封装。但是封装可能没有明确的代理类。请参阅我的编辑。 –

0

您必须实现数组下标操作:

int& operator[](std::size_t i) { return data[i]; } 
+0

它不足以支持二维数组。 – paweldac

+0

@paweldac:当然,这是一个例子。一个或者需要返回相应的向量,或者创建一个包装器。 – erenon

1

您需要一种方式,它会回到上,你可以再次使用operator[]得到结果的代理对象实现operator[]

示例代码:

struct matrix 
{ 
    struct Proxy 
    { 
     std::vector<int>* vec; 

     Proxy(std::vector<int>* vec_) 
      : vec(vec_) 
     { 
     } 

     int& operator[](int index) 
     { 
      return (*vec)[index]; 
     } 
    }; 

    matrix(int c, int r) : col(c), row(r), data(c, std::vector<int>(r)) 
    { 
    } 

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

    int col, row; 
    std::vector<std::vector<int>> data; 
};