Я переношу код, который использует очень большой массив float, что может привести к сбоям malloc с c до С++. Я задал вопрос о том, следует ли использовать векторы или знаки и Niki Yoshiuchi щедро предложил мне этот пример безопасного типа:
template<typename T>
class VectorDeque
{
private:
enum TYPE { NONE, DEQUE, VECTOR };
std::deque<T> m_d;
std::vector<T> m_v;
TYPE m_type;
...
public:
void resize(size_t n)
{
switch(m_type)
{
case NONE:
try
{
m_v.resize(n);
m_type = VECTOR;
}
catch(std::bad_alloc &ba)
{
m_d.resize(n);
m_type = DEQUE;
}
break;
}
}
};
Мне нужен 2D-вектор векторов /deque из deques, поэтому я изменил его на следующий код:
template<typename T>
class VectorDeque
{
private:
enum STORAGE_CONTAINER { NONE, DEQUE, VECTOR };
std::deque<std::deque<T> > x_d,y_d,z_d;
std::vector<std::vector<T> > x_v,y_v,z_v;
TYPE my_container;
public:
void resize(size_t num_atoms, size_t num_frames)
{
switch(m_type)
{
case NONE:
try
{
x_v.resize(num_atoms);
for (unsigned int couter=0;couter < num_frames; counter++)
x_v[counter].resize(num_frames);
y_v.resize(num_atoms);
for (unsigned int couter=0;couter < num_frames; counter++)
y_v[counter].resize(num_frames);
z_v.resize(num_atoms);
for (unsigned int couter=0;couter < num_frames; counter++)
z_v[counter].resize(num_frames);
my_container = VECTOR;
}
catch(std::bad_alloc &e)
{
x_d.resize(num_atoms);
for (unsigned int couter=0;couter < num_frames; counter++)
x_d[counter].resize(num_frames);
y_d.resize(num_atoms);
for (unsigned int couter=0;couter < num_frames; counter++)
y_d[counter].resize(num_frames);
z_d.resize(num_atoms);
for (unsigned int couter=0;couter < num_frames; counter++)
z_d[counter].resize(num_frames);
my_container = DEQUE;
}
break;
}
}
};
Теперь я хочу иметь возможность определять мои операторы скобок, чтобы я мог иметь инструкцию типа
x[1][2]
получить прямой доступ в зависимости от того, какой я использую реальный контейнер памяти (заданный значением моей перечислимой переменной.
Я видел пару обучающих программ, которые перемещаются вокруг переопределения оператора скобок, но не имеют никакой идеи переопределять двойные скобки.
Как вы можете перегрузить двойные скобки?
Кроме того, как бы вы перегружали двойные итераторы (в случае, если я хочу использовать итератор, в отличие от прямой индексации)?
ИЗМЕНИТЬ 1:
Основываясь на решении от Martin York/Matteo Italia, я разработал следующий класс:
template<typename T>
class VectorDeque2D
{
public:
class VectorDeque2D_Inner_Set
{
VectorDeque2D& parent;
int first_index;
public:
// Just init the temp object
VectorDeque2D_Inner_Set(My2D& p, int first_Index) :
parent(p),
first_Index(first_index) {}
// Here we get the value.
T& operator[](int second_index) const
{ return parent.get(first_index,second_index);}
};
// Return an object that defines its own operator[] that will access the data.
// The temp object is very trivial and just allows access to the data via
// operator[]
VectorDeque2D_Inner_Set operator[](unsigned int first_index) {
return (*this, x);
}
void resize_first_index(unsigned int first_index) {
try {
my_vector.resize(first_index);
my_container = VECTOR;
}
catch(std::bad_alloc &e) {
my_deque.resize(first_index);
my_container = DEQUE;
}
}
void resize_second_index(unsigned int second_index) {
try {
for (unsigned int couter=0;couter < my_vector.size(); counter++) {
my_vector[counter].resize(second_index);
}
my_container = VECTOR;
}
catch(std::bad_alloc &e) {
for (unsigned int couter=0;couter < my_deque.size(); counter++) {
my_deque[counter].resize(second_index);
}
my_container = DEQUE;
}
}
void resize(unsigned int first_index,
unsigned int second_index) {
try {
my_vector.resize(first_index);
for (unsigned int couter=0;couter < my_vector.size(); counter++) {
my_vector[counter].resize(second_index);
}
my_container = VECTOR;
}
catch(std::bad_alloc &e) {
my_deque.resize(first_index);
for (unsigned int couter=0;couter < my_deque.size(); counter++) {
my_deque[counter].resize(second_index);
}
my_container = DEQUE;
}
}
private:
enum STORAGE_CONTAINER { NONE, DEQUE, VECTOR };
friend class VectorDeque2D_Inner_Set;
std::vector<std::vector<T> > my_vector;
std::deque<std::deque<T> > my_deque;
STORAGE_CONTAINER my_container;
T& get(int x,int y) {
T temp_val;
if(my_container == VECTOR) {
temp_val = my_vector[first_index][second_index];
}
else if(my_container == DEQUE) {
temp_val = my_deque[first_index][second_index];
}
return temp_val;
}
};
Наконец, размерный 2D-контейнер! Спасибо, ребята!