我扩展了C ++ 11 std::array
,它是工作文件,但是当我尝试重载operator[]
时,我收到了这个错误:
error: lvalue required as left operand of assignment
array[0] = 911;
^~~
是否可以为operator[]
类型实施std::array
添加绑定检查?
这是代码:
#include <array>
#include <cassert>
#include <iostream>
template <unsigned int array_size, typename array_datatype=long int>
struct Array : public std::array<array_datatype, array_size>
{
Array()
{
}
// std::array constructor inheritance
// https://stackoverflow.com/questions/24280521/stdarray-constructor-inheritance
Array(std::initializer_list< array_datatype > new_values)
{
unsigned int data_size = new_values.size();
unsigned int column_index = 0;
// std::cout << data_size << std::endl;
if( data_size == 1 )
{
this->clear(*(new_values.begin()));
}
else
{
assert(data_size == array_size);
for( auto column : new_values )
{
(*this)[column_index] = column;
column_index++;
}
}
}
array_datatype operator[](unsigned int line)
{
assert(line < array_size);
assert(line > -1);
return (*this)[line];
}
/**
* Prints a more beauty version of the array when called on `std::cout<< array << std::end;`
*/
friend std::ostream& operator<<( std::ostream &output, const Array &array )
{
unsigned int column;
output << "{";
for( column=0; column < array_size; column++ )
{
output << array[column];
if( column != array_size-1 )
{
output << ", ";
}
}
output << "}";
return output;
}
}
相关:
答案 0 :(得分:4)
如果要在赋值的左侧使用operator[]
的返回值,则必须按引用返回数组元素,而不是按值返回。
您还有一个递归循环,因为您从内部调用自己的operator[]
。您想要调用基类的operator[]
,因此您需要对其进行限定。
试试这个:
array_datatype& operator[](unsigned int line)
{
assert(line < array_size);
assert(line > -1);
return std::array<array_datatype, array_size>::operator[](line);
}
答案 1 :(得分:2)
您可以使用:
array_datatype& operator[](unsigned int line)&
array_datatype const& operator[](unsigned int line)const&
array_datatype operator[](unsigned int line)&&
答案 2 :(得分:0)
如果要对数组元素进行绑定检查访问,只需使用at
(或std::vector
)的std::array
方法,而不是[]
运算符。就是出于那个目的,不要重新发明轮子:)。
有关数组边界检查的文档,请参阅reference。
答案 3 :(得分:0)
这是我对单维数组的解决方案:
#include <array>
#include <cassert>
#include <iostream>
template <unsigned int array_width, typename array_datatype=long int>
struct Array
{
/**
* Is it okay to inherit implementation from STL containers, rather than delegate?
* https://stackoverflow.com/questions/2034916/is-it-okay-to-inherit-implementation-from-stl-containers-rather-than-delegate
*/
std::array<array_datatype, array_width> _data;
/**
* std::array constructor inheritance
* https://stackoverflow.com/questions/24280521/stdarray-constructor-inheritance
*/
Array()
{
}
Array(std::initializer_list< array_datatype > new_values)
{
unsigned int data_size = new_values.size();
unsigned int column_index = 0;
// std::cout << data_size << std::endl;
if( data_size == 1 )
{
this->clear(*(new_values.begin()));
}
else
{
assert(data_size == array_width);
for( auto column : new_values )
{
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.
*
* How to implement bound checking for std::array?
* https://stackoverflow.com/questions/49419089/how-to-implement-bound-checking-for-stdarray
*
* @param line the current line you want to access
* @return a pointer to the current line
*/
array_datatype operator[](unsigned int line)&&
{
assert(line < array_width);
assert(line >= 0);
return this->_data[line];
}
array_datatype const& operator[](unsigned int line)const&
{
assert(line < array_width);
assert(line >= 0);
return this->_data[line];
}
array_datatype& operator[](unsigned int line)&
{
assert(line < array_width);
assert(line >= 0);
return this->_data[line];
}
void clear(array_datatype initial = 0)
{
unsigned int column_index = 0;
for( ; column_index < array_width; column_index++ )
{
this->_data[column_index] = initial;
}
}
/**
* The Array<> type includes the Matrix<> type, because you can multiply a `Array` by an `Matrix`,
* but not a vice-versa.
*/
void multiply(Array< array_width, Array< array_width, array_datatype > > &matrix)
{
unsigned int column;
unsigned int step;
array_datatype old_array[array_width];
for(column = 0; column < array_width; column++)
{
old_array [column] = this->_data[column];
this->_data[column] = 0;
}
for(column = 0; column < array_width; column++)
{
for(step = 0; step < array_width; step++)
{
this->_data[column] += old_array[step] * matrix._data[step][column];
}
}
// If you would like to preserve the original value, it can be returned here
// return old_array;
}
/**
* Prints a more beauty version of the array when called on `std::cout<< array << std::end;`
*/
friend std::ostream& operator<<( std::ostream &output, const Array &array )
{
unsigned int column;
output << "{";
for( column=0; column < array_width; column++ )
{
output << array._data[column];
if( column != array_width-1 )
{
output << ", ";
}
}
output << "}";
return output;
}
};
这是矩阵(多维)的扩展:
#include <cassert>
#include <iostream>
#include "array.h"
/**
* C++ Matrix Class
* https://stackoverflow.com/questions/2076624/c-matrix-class
*
* A proper way to create a matrix in c++
* https://stackoverflow.com/questions/618511/a-proper-way-to-create-a-matrix-in-c
*
* error: incompatible types in assignment of 'long int (*)[4]' to 'long int [4][4]'
* https://stackoverflow.com/questions/49312484/error-incompatible-types-in-assignment-of-long-int-4-to-long-int
*/
template <unsigned int matrix_width=3, unsigned int matrix_height=3, typename matrix_datatype=long int>
struct Matrix : public Array< matrix_height, Array< matrix_width, matrix_datatype > >
{
Matrix()
{
}
Matrix(matrix_datatype initial)
{
this->clear(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++;
}
}
void clear(matrix_datatype initial=0)
{
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;
}
}
}
void multiply(Matrix &matrix)
{
unsigned int line;
unsigned int column;
unsigned int step;
matrix_datatype old_matrix[matrix_height][matrix_width];
for(line = 0; line < matrix_height; line++)
{
for(column = 0; column < matrix_width; column++)
{
old_matrix [line][column] = this->_data[line][column];
this->_data[line][column] = 0;
}
}
for(line = 0; line < matrix_height; line++)
{
for(column = 0; column < matrix_width; column++)
{
for(step = 0; step < matrix_width; step++)
{
this->_data[line][column] += old_matrix[line][step] * matrix._data[step][column];
}
// std::cout << "this->_data[line][column] = " << this->_data[line][column] << std::endl;
}
}
// If you would like to preserve the original value, it can be returned here
// return old_matrix;
}
/**
* 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;
}
};
这是一个简单的测试应用程序:
#include "array.h"
#include "matrix.h"
void array_tests();
void matrix_tests();
/**
* To build it use:
* g++ -std=c++11 test.cpp -o main
*/
int main (int argc, char* argv[])
{
array_tests();
std::cout << std::endl;
matrix_tests();
}
// struct Matrixx : public Array< 3, Array< 3, int > >
// {
// };
void array_tests()
{
std::cout << "Array tests" << std::endl;
Array<3, long int> array;
array[1] = 99911;
std::cout << array << std::endl;
std::cout << array[1] << std::endl;
std::cout << array[2] << 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;
}
运行它,你会看到:
Array tests
{0, 99911, 0}
99911
0
array2: {0, 0, 0}
array3: {3, 3, 3}
Matrix tests
{{39593264, 0, 1875895727}, {0, 39593264, 0}, {1875566066, 0, -927864272}}
{{911, 0, 1875895727}, {0, 39593264, 0}, {1875566066, 0, -927864272}}
{911, 0, 1875895727}
911
{{0, 0, 0}, {0, 0, 0}, {0, 0, 0}}
{{3, 3, 3}, {3, 3, 3}, {3, 3, 3}}
{{4, 4, 4}}