Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Центр помощи > [C++]Перегрузка оператора []


Автор: Vo1Ce 22.4.2010, 17:04
Надеюсь не повторяюсь. С++
 Нужно ?перегрузить опертор? [], в классе с, к примеру, двумерным массивом. Таким оброзом, чтобы обращаться к элементам массива можно было MyClass[line,column], а не как обычно MyClass[line][column] ... Интерисуют конткретно методы перегрузки оператора [] методы реализации такой записи.

Автор: ToTToRo 23.4.2010, 05:06
А разве так можно?

Автор: t_gran 23.4.2010, 05:08
Vo1Ce, вы сами понимаете что написали? Покажите компилятор который это проглотит:
Код

int main ()
{
   int abc[1][1];
   abc[0,0]= 1;
   return 0;
}


Автор: GoldFinch 23.4.2010, 08:42
Vo1Ce, operator[] - бинарный, он поддерживает только один операнд внутри []
вы можете перегрузить operator, (запятую) для своего типа индекса, но тогда придется писать

foo[idx_t(1), 1]

Автор: Vo1Ce 23.4.2010, 10:11
Цитата(GoldFinch @ 23.4.2010,  08:42)
Vo1Ce, operator[] - бинарный, он поддерживает только один операнд внутри []
вы можете перегрузить operator, (запятую) для своего типа индекса, но тогда придется писать

foo[idx_t(1), 1]

это уже интересней, спасибо. Можно пример какой-нибудь? Я не подумал о возможности перегрузки оператора запятая...  Или вообще, есть какие-нибудь ещё методы, чтобы использовать запись [...,...]. (в голову только пирходило то, что бы в [] вводить строку, ну тогда, я не уверен с тем, как избавиться от ввода ковычек.

 з.ы. каким задание я понял, таким и написал... Может перегрузка [] и не возможна по нескольким операндам, но я думаю теперь суть того, что мне надо ясна...

add: что-то я самостоятельно не могу разобраться с перегрузкой запятой. Я как понял, он является и бинарным и унарным в различных случаях? Ну конкретно ничего из него я получить так и не смог...

Автор: GoldFinch 23.4.2010, 17:44
Код

struct index_t
{
   index_t(int i) : value(i) {}
   int value;
};

struct index2_t
{
   index2_t(int i_, int j_) : i(i_), j(j_) {}
   int i, j;
};

template<typename T, int N, int M>
struct matrix_t
{
   T data[N*M];
   T& operator[](index2_t index)
   {
       return data[index.i + index.j * N];
   }
};

// index2_t operator,(int i, int j)  - не заработает
// т.к. нельзя перегрузить для аргументов встроенных типов

index2_t operator,(index_t i, index_t j)
{
   return index2_t(i.value, j.value);
}
index2_t operator,(int i, index_t j)
{
   return index2_t(i, j.value);
}
index2_t operator,(index_t i, int j)
{
   return index2_t(i.value, j);
}

int main()
{
   matrix_t<int, 10, 5> m;
   for(int i = 0; i != 10*5; ++i)
       m.data[i] = i;

   cout << m[index_t(1), 2] << '\n';
   cout << m[3, index_t(4)] << '\n'; 
}


Автор: Sartorius 23.4.2010, 18:30
Vo1Ce, не заморачивайтесь. Перегружайте operator(). Какая вам разница круглые скобки или квадратные?

Автор: Vo1Ce 23.4.2010, 20:35
GoldFinch, спасибо, буду разбираться. Идей нет, как можно сделать, чтобы запись всё же не обращалась так явно к классу?

Sartorius, к сожалению задание именно такое =), ничего поделать не могу, не для себя делаю...

Автор: GoldFinch 23.4.2010, 22:19
Vo1Ce, явное обращение к классу можно заменить явным обращением к переменной этого класса %)

т.е. вместо [T(1), 2]
например [t+1, 2]  (вместо "+" - любой бинарный оператор, тип t - T)

вобщем надо чтобы один из операндов бинарного оператора имел пользовательский тип

Автор: Vo1Ce 23.4.2010, 22:24
это конечно да, и для меня труда не составит всё оформить =) но интересно узнать, каким образом осуществить именно такую запись [line,column]. Вобщем спасибо GoldFinch, вы мне многим помогли. Но вопрос остаётся не закрытым, если кто знает или узнает методы, сообщите, сдача задачи на след неделе...

Автор: GoldFinch 23.4.2010, 23:09
есть еще один весьма сомнительный способ - объявить глобальные переменные типа index_t
_0, _1, _2, _3, ... (много)
т.е.

index_t _0(0);
index_t _1(1);
index_t _2(2);
...

в принципе пару сотен таких переменных можно сгенерить скриптом.

тогда код будет такой a[_1, 2]

причем эти переменные можно объявить не в глобальной области видимости, а в области видимости operator,(index_t, int)

Автор: Vo1Ce 24.4.2010, 17:26
ух отлично, так у меня получилось, только при обьявлении их в видимости оператора не компилируется... Пишет что не заданы. 
  А может быть возможным, каким либо образом, обьединие "[" как часть оператора и как идентификатор... т.е.  в данном случае запись [[1,2] заменить на [1,2] неким заклинанием? 
 Если всё же кто-то знает или разгадает секрет какого-то метода для записи [...,...] жду с нетерпением, заранее всем спасибо и спасибо всем, кто уже откликнулся.

Автор: GoldFinch 24.4.2010, 17:31
Цитата(Vo1Ce @  24.4.2010,  18:26 Найти цитируемый пост)
А может быть возможным, каким либо образом, обьединие "[" как часть оператора и как идентификатор... т.е.  в данном случае запись [[1,2] заменить на [1,2] неким заклинанием? 


только своим препроцессором. язык такого не позволяет

Автор: Vo1Ce 24.4.2010, 20:28
 Извините, а зашаблонить нельзя как-нибудь опертор запятую. Чтобы например если вводишь один операнд инт и другой инт, то он первый его операнд переделывет в какой-нить класс\структуры с эелментом, равным этому инт и дальше работал так? 
  И ещё мне предложили использовать макрос, и просто заменить () на []. Но от этого появляются кое-какие неудобства  и у меня такой вопрос, вообще обе эти идеи будут работать? и если сделать #define на участок программы где класс , и соответсвенно #undef в конце класса, то при вызове MyClass[1,2] , где в классе [] заменены на (), то компилятор будет жаловаться? кто-нибудь проверить может?
 Спрашиваю вас, т.к. уехал от рабочего места до понедельника, и сейчас нет возможности проверить это всё. Заранее спасибо.

Автор: GoldFinch 25.4.2010, 20:13
шаблоны тут не помогут.

с макросом - вообще не понял как это %)

Автор: Vo1Ce 26.4.2010, 17:55
блин, да, кажется из этого ничто не получится (макрос вообще может быть только именной, что нвоое я для себя узнал =) ). Скоро сдавать надо, может кто может у кого поарспрашивать, например. Нужна конкретно запись [1,2]. 
 Ещё вроде на коуднэтэ наткнулся на старый топик (06 года), заданое такое, но результат вроде не получен, я лишь нашёл код, который позволяет обращаться к массиву вот так

 int a=1;
MyClass[a,2];

 но запись MyClass[1,2] не работает (
 
 Там вроде использовались шаблоны на класс (только для инициализации) и шаблон на оператор запятую, если надо найду код сегодня.

 //Или кто знает на какой форум лучше обартиться, где наверняка могут помочь? Время уже жмёт. Самому видать знаний и практики не хватает =(

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)