Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/148.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 试图理解C+中矩阵乘法的存取算子+;_C++ - Fatal编程技术网

C++ 试图理解C+中矩阵乘法的存取算子+;

C++ 试图理解C+中矩阵乘法的存取算子+;,c++,C++,我试图理解矩阵乘法的存取运算符 模板 类Matrix44 { 公众: Matrix44(){} //接下来的两行对我来说完全混淆了 常量T*运算符[](uint8_T i)常量{return m[i];} T*运算符[](uint8_T i){返回m[i];} //用单位矩阵的系数初始化矩阵的系数 T m[4][4]={{1,0,0,0},{0,1,0,0},{0,0,1,0},{0,0,0,1};//你为什么能这样做m[4][4] }; 类型定义矩阵X44矩阵X44F; 因此,我的理解是

我试图理解矩阵乘法的存取运算符

模板
类Matrix44
{ 
公众:
Matrix44(){}
//接下来的两行对我来说完全混淆了
常量T*运算符[](uint8_T i)常量{return m[i];}
T*运算符[](uint8_T i){返回m[i];}
//用单位矩阵的系数初始化矩阵的系数
T m[4][4]={{1,0,0,0},{0,1,0,0},{0,0,1,0},{0,0,0,1};//你为什么能这样做m[4][4]
}; 
类型定义矩阵X44矩阵X44F;
因此,我的理解是,他们定义了自己的访问操作符,用于访问矩阵索引:

Matrx44f材料;
mat[0][3]=1.f;
但这与他们的定义有什么关系呢

。。。
常量T*运算符[](uint8_T i)常量{return m[i];}
T*运算符[](uint8_T i){返回m[i];}

非常感谢您帮助C++ NoOb

,因为有不少人已经指出它是一个相当强的>差的矩阵实现< /强>:它让我们假设内部实现,并有一些缺陷。但如果我说我在研究代码中还没有见过这样的实现,那我就撒谎了除了抨击实现,我想简单地指出它是如何工作的,尽管它显示了C++的一些特殊性。 概述

// Class for a generic data type T (e.g. T = float)
template<typename T> 
class Matrix44 { 
public: 
  // Constructor
  Matrix44() {
    return;
  } 
  // Access operator for constant objects
  const T* operator [] (uint8_t i) const {
    return m[i];
  }
  // Access operator for non-constant objects
  T* operator [] (uint8_t i) {
    return m[i];
  }
  // Declaration of a stack-allocated array as class member
  T m[4][4] 
  // Initialisation of this class member
  = {{1,0,0,0},{0,1,0,0},{0,0,1,0},{0,0,0,1}};
};

// Alias Matrix44f for a matrix of floats (T = float)
typedef Matrix44<float> Matrix44f; 

将是a的声明,可使用

int m[2][3] = {{1,2},{3,4},{5,6}};
(类似于用an初始化向量向量的方式),然后可以用类似的语法
m[i][j]
访问其元素(也类似于向量向量
std::vector
,注意:没有越界检查!)

如您所见,您的类仅是泛型类型
T
的此类堆栈分配二维数组的包装器

T m[4][4];
所谓的
模板类
。将类实例化为
Matrix44
将使其成为
T=float
的矩阵,而对于矩阵
Matrix44
而言,基础数据类型将是
int
。使用底部的
typedef matrix4 matrix4f
创建此数据类型的新别名。因此可以声明一个变量
Matrix44f mat

Stack allocated(堆栈分配)意味着它的大小与堆分配的数组相比非常有限,而堆分配的数组对于
4x4
数组不是非常禁止(但为什么不将此实现至少扩展到
NxN
?)。此外,它的编写方式甚至没有正确的构造函数(
Matrix44(){}
),而是默认使用标识矩阵初始化

{{1,0,0,0},{0,1,0,0},{0,0,1,0},{0,0,0,1}}
(为什么会有人这么做?)

操作员[]

C++提供了重载运算符的可能性。因此,我们可以定义(重载)基本操作,如加法
运算符+
、乘法
运算符*
、比较等。同样,我们也可以重载
[]
(但仅使用一个参数,因此像
特征值
这样的数字库选择重载
()
运算符),
()
。但是没有什么过载!为了允许类外使用类似于堆栈分配数组的
[]
访问矩阵,选择编写运算符
[]
返回指向底层二维数组第二维第一个元素的指针,该元素位于第一维
m[i][0]
的相应索引
i
返回m[i]
相当于
返回&m[i][0]
。然后可以应用指针的操作符
[]
p[j]
,它相当于
*(p+j)
(有关更多详细信息,请参阅)通过j项移动此指针,以访问元素
m[i][j]
。(这类似于使用向量向量而不是堆栈分配的数组,从操作符
[]
返回
std::vector&
,然后使用向量的
[]
操作符访问精确的元素。)

成员函数可以声明为常量(请参见参数列表后的
const
),这意味着也可以为常量对象调用它们,而如果未声明为常量,则只能为非常量对象调用它们。对于常量对象,调用常量版本,而对于非常量对象,调用非常量实现()。为了允许分配非恒定版本

T* operator [] (uint8_t i) {
  return m[i];
}
返回一个非常量指针
T*
,当常量实现返回一个指向常量变量
const T*
的指针时,可以修改该指针

const T* operator [] (uint8_t i) const { 
  return m[i];
}

这就是为什么有两个这样的实现。对于常量对象,将调用不允许赋值的后一个对象(但您可以使用
m[1][2]
读取元素
1,2
),而对于非常量对象,将调用允许赋值的第一个对象(例如
m[1][2]=1
将元素
1,2
设置为
1
).

正如许多人已经指出的那样,它是一个非常差的矩阵实现
:让我们对内部实现进行假设,并且有相当多的缺陷。但如果我说我在研究代码中还没有见过这样的实现,那我就撒谎了除了抨击实现,我想简单地指出它是如何工作的,尽管它显示了C++的一些特殊性。 概述

// Class for a generic data type T (e.g. T = float)
template<typename T> 
class Matrix44 { 
public: 
  // Constructor
  Matrix44() {
    return;
  } 
  // Access operator for constant objects
  const T* operator [] (uint8_t i) const {
    return m[i];
  }
  // Access operator for non-constant objects
  T* operator [] (uint8_t i) {
    return m[i];
  }
  // Declaration of a stack-allocated array as class member
  T m[4][4] 
  // Initialisation of this class member
  = {{1,0,0,0},{0,1,0,0},{0,0,1,0},{0,0,0,1}};
};

// Alias Matrix44f for a matrix of floats (T = float)
typedef Matrix44<float> Matrix44f; 

将是a的声明,可使用

int m[2][3] = {{1,2},{3,4},{5,6}};
(类似于使用an初始化向量向量的方式),然后可以使用类似的语法
m[i]访问其元素
    using reference = T(&)[4]; // reference to a 4-element subarray
    reference const operator[](int i) const { return m[i]; }
    reference       operator[](int i)       { return m[i]; }
template<class T> using Matrix44 = std::array<std::array<T, 4>, 4>;
template<typename T> 
class Matrix44 
{ 
public: 
    Matrix44() {} 
    // The next two lines are totally confusing for me
    decltype(auto) operator [] (uint8_t i) const { return m[i]; }
    decltype(auto) operator [] (uint8_t i)       { return m[i]; }
    // initialize the coefficients of the matrix with the coefficients of the identity matrix
    std::array<std::array<T, 4>, 4> m = {{1,0,0,0},{0,1,0,0},{0,0,1,0},{0,0,0,1}};
}; 
 
typedef Matrix44<float> Matrix44f;