我正在尝试构建我自己的Matrix
类型,它使用多维数组作为标准C
矩阵。到目前为止,这是我的实现:
#include <iostream>
/**
* To build it use:
* g++ -std=c++11 test_template_initicialization.cpp -o main
*/
template <int width, int height>
struct Matrix
{
long int _data[height][width];
Matrix()
{
}
Matrix(long int matrix[height][width]) : _data(matrix)
{
}
/**
* Overloads the `[]` array access operator, allowing you to access this class objects as the
* where usual `C` arrays.
*
* @param line the current line you want to access
* @return a pointer to the current line
*/
long int* operator[](int line)
{
return this->_data[line];
}
/**
* Prints a more beauty version of the matrix when called on `std::cout<< matrix << std::end;`
*/
friend std::ostream &operator<<( std::ostream &output, const Matrix &matrix )
{
int i, j;
for( i=0; i < height; i++ )
{
for( j=0; j < width; j++ )
{
output << matrix._data[i][j] << ", ";
}
output << matrix._data[i][j] << "\n";
}
return output;
}
};
/**
* C++ Matrix Class
* https://stackoverflow.com/questions/2076624/c-matrix-class
*/
int main (int argc, char *argv[])
{
Matrix<3, 3> matrix;
std::cout << matrix << std::endl;
matrix[0][0] = 911;
std::cout << matrix << std::endl;
std::cout << matrix[0] << std::endl;
std::cout << matrix[0][0] << std::endl;
Matrix<4,4> matrix2 = { 0 };
}
构建最后一个示例Matrix<4,4> matrix2 = { 0 };
时,我遇到了不兼容的类型错误:
D:\test_template_initicialization.cpp: In instantiation of 'Matrix<width, height>::Matrix(long int (*)[width]) [with int width = 4; int height = 4]':
D:\test_template_initicialization.cpp:67:29: required from here
D:\test_template_initicialization.cpp:16:56: error: incompatible types in assignment of 'long int (*)[4]' to 'long int [4][4]'
Matrix(long int matrix[height][width]) : _data(matrix)
错误的主要部分是'long int (*)[4]' to 'long int [4][4]'
。 long int (*)[4]
来自matrix2 = { 0 };
,long int [4][4]
是我的标准类模板声明long int _data[height][width];
。
我可以修复我的Matrix
构造函数,以便它可以接受来自long int (*)[4]
初始化调用的matrix2 = { 0 };
吗?
答案 0 :(得分:0)
我设法在以下链接的帮助下解决了这个问题:
固定代码:
#include <cassert>
#include <iostream>
template <unsigned int array_width, typename array_datatype=long int>
struct Array
{
array_datatype _data[array_width];
Array()
{
}
Array(std::initializer_list< array_datatype > raw_data)
{
unsigned int data_size = raw_data.size();
unsigned int column_index = 0;
// std::cout << data_size << std::endl;
if( data_size == 1 )
{
array_datatype initial = *(raw_data.begin());
for( ; column_index < array_width; column_index++ )
{
this->_data[column_index] = initial;
}
}
else
{
assert(data_size == array_width);
for( auto column : raw_data )
{
this->_data[column_index] = column;
column_index++;
}
}
}
/**
* Overloads the `[]` array access operator, allowing you to access this class objects as the
* where usual `C` arrays.
*
* @param line the current line you want to access
* @return a pointer to the current line
*/
array_datatype* operator[](int line)
{
return this->_data;
}
/**
* Prints a more beauty version of the matrix when called on `std::cout<< matrix << std::end;`
*/
friend std::ostream &operator<<( std::ostream &output, const Array &matrix )
{
unsigned int column;
output << "{";
for( column=0; column < array_width; column++ )
{
output << matrix._data[column];
if( column != array_width-1 )
{
output << ", ";
}
}
output << "}";
return output;
}
};
template <unsigned int matrix_width, unsigned int matrix_height, typename matrix_datatype=long int>
struct Matrix
{
matrix_datatype _data[matrix_height][matrix_width];
Matrix()
{
}
Matrix(matrix_datatype initial)
{
unsigned int line;
unsigned int column;
for( line=0; line < matrix_height; line++ )
{
for( column=0; column < matrix_width; column++ )
{
this->_data[line][column] = initial;
}
}
}
Matrix(std::initializer_list< std::initializer_list< matrix_datatype > > raw_data)
{
// std::cout << raw_data.size() << std::endl;
assert(raw_data.size() == matrix_height);
// std::cout << raw_data.begin()->size() << std::endl;
assert(raw_data.begin()->size() == matrix_width);
unsigned int line_index = 0;
unsigned int column_index;
for( auto line : raw_data )
{
column_index = 0;
for( auto column : line )
{
this->_data[line_index][column_index] = column;
column_index++;
}
line_index++;
}
}
/**
* Overloads the `[]` array access operator, allowing you to access this class objects as the
* where usual `C` arrays.
*
* @param line the current line you want to access
* @return a pointer to the current line
*/
matrix_datatype* operator[](int line)
{
return this->_data[line];
}
/**
* Prints a more beauty version of the matrix when called on `std::cout<< matrix << std::end;`
*/
friend std::ostream &operator<<( std::ostream &output, const Matrix &matrix )
{
unsigned int line;
unsigned int column;
output << "{";
for( line=0; line < matrix_height; line++ )
{
output << "{";
for( column=0; column < matrix_width; column++ )
{
output << matrix._data[line][column];
if( column != matrix_width-1 )
{
output << ", ";
}
}
if( line != matrix_height-1 )
{
output << "}, ";
}
else
{
output << "}";
}
}
output << "}";
return output;
}
};
void array_tests()
{
std::cout << "Array tests" << std::endl;
Array<3, long int> array;
std::cout << array << std::endl;
std::cout << array[0] << std::endl;
Array<3> array2 = {0,0,0};
std::cout << "array2: " << array2 << std::endl;
Array<3> array3 = {3};
std::cout << "array3: " << array3 << std::endl;
}
void matrix_tests()
{
std::cout << "Matrix tests" << std::endl;
Matrix<3, 3, long int> matrix;
std::cout << matrix << std::endl;
matrix[0][0] = 911;
std::cout << matrix << std::endl;
std::cout << matrix[0] << std::endl;
std::cout << matrix[0][0] << std::endl;
Matrix<3, 3> matrix2{ {0,0,0}, {0,0,0}, {0,0,0} };
std::cout << matrix2 << std::endl;
Matrix<3, 3> matrix3 = { 3 };
std::cout << matrix3 << std::endl;
Matrix<3, 1, long int> matrix4 = { 4 };
std::cout << matrix4 << std::endl;
}
/**
* To build it use:
* g++ -std=c++11 main.cpp -o main
*/
int main (int argc, char *argv[])
{
matrix_tests();
std::cout << std::endl;
array_tests();
}
运行这个,你得到:
Matrix tests
{{4200800, 0, -928274330}, {32765, 14354248, 0}, {-1499063668, 0, 24}}
{{911, 0, -928274330}, {32765, 14354248, 0}, {-1499063668, 0, 24}}
0x65fde0
911
{{0, 0, 0}, {0, 0, 0}, {0, 0, 0}}
{{3, 3, 3}, {3, 3, 3}, {3, 3, 3}}
{{4, 4, 4}}
Array tests
{0, 1875566066, 0}
0x65fdf4
array2: {0, 0, 0}
array3: {3, 3, 3}