Russian Qt Forum

Программирование => С/C++ => Тема начата: Igors от Апрель 13, 2012, 12:14



Название: Оператор [] вместо get/set [РЕШЕНО]
Отправлено: Igors от Апрель 13, 2012, 12:14
Добрый день

Есть структура с методами get/set

Код
C++ (Qt)
struct CArray {
...
int Get( size_t index ) const;
void Set( size_t index. int val );
};
 
Хотелось бы иметь возможность писать так
Код
C++ (Qt)
CArray arr;
..
for (int i = 0; i < limit; ++i)
if (arr[i] < 0) arr[i] = 0;
 
Ссылки на int я не имею, понимаю что не могу взять адрес от такого "элемента" - ничего, обойдусь, мне бы просто присваивание удобно писать в стиле массива, а не размазывать set. Как это сделать?

Спасибо
 


Название: Re: Оператор [] вместо get/set
Отправлено: m_ax от Апрель 13, 2012, 12:34
А как у Вас set и get реализованы?

И что значит:
Цитировать
Ссылки на int я не имею, понимаю что не могу взять адрес от такого "элемента"...
?


Название: Re: Оператор [] вместо get/set
Отправлено: Bepec от Апрель 13, 2012, 12:48
Эммм... а что мешает оператор индексации переопределить?

И что скрывается за ... в структуре? В чём хранишь значения?


Название: Re: Оператор [] вместо get/set
Отправлено: Igors от Апрель 13, 2012, 14:22
А как у Вас set и get реализованы?
И что скрывается за ... в структуре? В чём хранишь значения?
Да все что угодно, важно что "не int", поэтому переопределить [] по известным образцам я не могу, т.к. не на что вернуть ссылку. Напр

Код
C++ (Qt)
void CArray::Set( size_t index, int val )
{
mReal[index] = double(val);  // mReal, mImage - контейнеры double
mImage[index] = 0.0;
}
 


Название: Re: Оператор [] вместо get/set
Отправлено: Blackwanderer от Апрель 13, 2012, 14:33
тут без set'а не получится: нужно присваивать двум переменным за раз.


Название: Re: Оператор [] вместо get/set
Отправлено: m_ax от Апрель 13, 2012, 14:36
тут без set'а не получится: нужно присваивать двум переменным за раз.
Да в принципе можно) Только это будет совсем не тривиально и как законный вопрос - оно вообще надо?

Другой вариант..
Организовать массив с элементами std::complex<double>... Хотя, наверно это предлагать бесполезно) Потом выясниться, что там вообще всё что угодно может быть.. и .т.д. и т.п. )


Название: Re: Оператор [] вместо get/set
Отправлено: ddrtn от Апрель 13, 2012, 14:39
Код:
class CArray 
{
...............
int operator[] (size_t idx) const;
int& operator[] (size_t idx);
...............
};


Название: Re: Оператор [] вместо get/set
Отправлено: m_ax от Апрель 13, 2012, 14:45
Код:
class CArray 
{
...............
int operator[] (size_t idx) const;
int& operator[] (size_t idx);
...............
};
И как это Igors до такого сразу не догадался?  :)


Название: Re: Оператор [] вместо get/set
Отправлено: sudo от Апрель 13, 2012, 14:55
Я тут набросал примитивный вариантик :)

Код
C++ (Qt)
#include <QCoreApplication>
#include <QDebug>
 
 
struct Array
{
int get(size_t /*index*/) const { return 0; }
void set(size_t /*index*/, int /*val*/) {}
 
int& operator[](int index);
QList<int> m_list;
};
 
 
int& Array::operator[](int index)
{
 return m_list[index];
}
 
 
int main(int argc, char *argv[])
{
 QCoreApplication a(argc, argv);
 
 Array array;
 array.m_list << 1 << 2 << 3 << 4 << 5 << 6 << 7;
 
 qDebug() << array[2];
 
 array[2] = 100500;
 
 qDebug() << array[2];
 
 return a.exec();
}
 
 

Только на интах, а не на сайз_т, как-то само так получилось :D Ну и с проектом не заморачивался


Название: Re: Оператор [] вместо get/set
Отправлено: sudo от Апрель 13, 2012, 14:59
А как у Вас set и get реализованы?
И что скрывается за ... в структуре? В чём хранишь значения?
Да все что угодно, важно что "не int", поэтому переопределить [] по известным образцам я не могу, т.к. не на что вернуть ссылку. Напр

Код
C++ (Qt)
void CArray::Set( size_t index, int val )
{
mReal[index] = double(val);  // mReal, mImage - контейнеры double
mImage[index] = 0.0;
}
 

А вот с таким что делать, надо думать...


Название: Re: Оператор [] вместо get/set
Отправлено: Igors от Апрель 13, 2012, 15:05
Код:
class CArray 
{
...............
int operator[] (size_t idx) const;
int& operator[] (size_t idx);
...............
};
Мил-человек, разговор с глухими утомляет. Третий раз говорю - НЕТ (отсутствует) у структуры int на который можно вернуть ссылку.

...и как законный вопрос - оно вообще надо?
Ну я же Вас не спрашиваю, зачем/кому нужна Ваша реализация слот/сигнал. Потому что понимаю что интересно "как это сделать", а применения найдутся (обычно уже есть)

Никто не утверждает что так "надо делать". Но есть случаи когда такая конструкция была бы удобной/полезной. Особенно при шаблонизировании (столь любимом некоторыми из нас)



Название: Re: Оператор [] вместо get/set
Отправлено: m_ax от Апрель 13, 2012, 15:27
Всё гениальное - просто)

Код
C++ (Qt)
class adapter
{
public:
   adapter(int& tmp, double& re, double& im )
       : m_tmp(tmp), m_re(re), m_im(im) {}
   int& value() { return m_tmp; }
   ~adapter() {
       m_re = m_tmp;
       m_im = 0.0;
   }
private:
   int& m_tmp;
   double& m_re;
   double& m_im;
};
 
struct CArray
{
   CArray() {}
 
   int& operator[](size_t index) {
       double& re = mReal[index];
       double& im = mReal[index];
       adapter adap(m_tmp, re, im);
       return adap.value();
   }
 
   enum {SIZE = 100};
   double mReal[SIZE];
   double mImag[SIZE];
   int m_tmp;
};
 
int main()
{
   CArray arr;
   arr[1] = 2;
   std::cout << arr[1] << std::endl;
   return 0;
}
 
Это для записи. Для чтения почти аналогично пишется)


Название: Re: Оператор [] вместо get/set
Отправлено: m_ax от Апрель 13, 2012, 16:51
Да, сорри) Мой вариант выше - это плохое решение(( Так делать нельзя(


Название: Re: Оператор [] вместо get/set
Отправлено: kamre от Апрель 13, 2012, 17:52
Как это сделать?

Можно через промежуточный класс:
Код:
#include <iostream>

class CArray {
public:
  int get(int index) const {
    int res = (index & 1) ? 1 : -1;
    std::cout << "get(" << index << ") = " << res << std::endl;
    return res;
  }
  void set(int index, int value) {
    std::cout << "set(" << index << ", " << value << ")" << std::endl;
  }

  struct Helper {
    CArray& a;
    int i;
    Helper(CArray& _a, int _i) : a(_a), i(_i) {}
    Helper& operator=(int value) { a.set(i, value); return *this; }
    operator int() { return a.get(i); }
  };

  Helper operator[](int index) { return Helper(*this, index); }
};

int main()
{
  CArray arr;
  for (int i = 0; i < 10; ++i) {
    if (arr[i] < 0) arr[i] = 0;
  }
  return 0;
}


Название: Re: Оператор [] вместо get/set
Отправлено: Igors от Апрель 13, 2012, 18:14
Можно через промежуточный класс:
Все четко. Спасибо


Название: Re: Оператор [] вместо get/set [РЕШЕНО]
Отправлено: whitecemetery от Апрель 26, 2012, 13:26
Ух, красота. =)