我正在编写自己的2d矩阵类。我想设计这个类的使用非常接近真正的数学符号。例如,我想要将元素作为 矩阵[3,6] 进行访问。但是c ++没有提供这种能力,但我可以通过下一种方式访问基本的多维数组:
int matrix[2][2] = {};
int val = matrix[1][0];
所以我决定创建返回基数组的函数。对于这个角色,最好的函数是operator()。所以我可以通过下一个方式访问:matrix()[1] [0]。好的,我开始实施它并坚持:(。看看我有什么:
template <typename ValType>
class Matrix2D
{
protected:
ValType m_data[2][2] = {};
public:
ValType** operator()() // <--- what type?
{
return m_data;
}
}
但是我在上面的函数中收到了编译器错误
错误C2440:'return':无法从'double [2] [2]'转换为'double **'
我理解错误,但不知道我必须改变什么来避免这个错误?函数必须返回什么类型?
答案 0 :(得分:6)
2D阵列衰减到指向其第一个“线”的指针。以下应该有效:
typedef ValType Line[2];
Line* operator()()
{
return m_data;
}
您可以以类似的方式使索引工作:
ValType* operator[](int line)
{
return m_data[line];
}
答案 1 :(得分:6)
由于这是标记的C ++ 11,因此您应该使用std::array
。并使用索引运算符,而不是调用运算符:
template <typename ValType>
class Matrix2D
{
protected:
using Row = std::array<ValType, 2>;
std::array<Row, 2> m_data;
public:
Row& operator[](size_t idx)
{
return m_data[idx];
}
};
这样你就可以写matrix[1][0]
而不必写matrix()[1][0]
(坦率地说,这看起来像是一个错字)。
此外,如果您希望同时执行两个索引,则可以编写调用运算符以简单地同时执行:
ValueType& operator()(size_t x, size_t y) {
return m_data[x][y];
}
这将允许您matrix(1, 0)
替代matrix[1][0]
。
答案 2 :(得分:1)
您选择的类型取决于您。:)例如
ValType ( * operator()() )[2]
{
return m_data;
}
当一个数组从函数返回值时,它会被隐式转换为指向其frist元素的指针。你有一个二维数组声明为
ValType m_data[2][2] = {};
因此它的元素又是ValType[2]
类型的一维数组。因此,指向这样一个对象(数组的第一个元素)的指针将被声明为
ValType ( *p )[2] = m_data;
或者
ValType ( & operator()() )[2][2]
{
return m_data;
}
在这种情况下,该函数返回对数组的引用。函数可能不会返回数组themselvez,但它们可能会返回对数组的引用。您可以通过以下方式使用功能
ValType( &a )[2][2] = obj(); // where obje is an object of the template class
或者你可以写更简单的
auto &a = obj();
甚至喜欢
ValType ( * operator()() )[2][2]
{
return &m_data;
}
此用例与第一个用例类似,只是函数返回指向整个数组的指针。
在所有三种情况下,你可以使用一些使代码更简单的typedef。但无论如何你需要知道我展示的合成器。
考虑到类定义的右大括号后必须有分号。:)