оператор '+' для указателей
От: Lorenzo_LAMAS  
Дата: 24.05.04 06:08
Оценка:
Есть выражение а + 2; Если а — указатель, ссылка на указатель, массив, ссылка на массив — все ок. Если а

class A
{
public:
    operator int *();
};

void g()
{
   A a;
   a + 2;
}


То тоже все нормально. Но почему в таком случае возникают проблемы?
class A
{
public:
    typedef int (&RARR_t)[2];
    operator RARR_t();
};

void g()
{
   A a;
   a + 2;
}


Комо онлайн такое не компилирует. VC 7.1 — все ок.
Of course, the code must be complete enough to compile and link.
Re: оператор '+' для указателей
От: jazzer Россия Skype: enerjazzer
Дата: 24.05.04 07:49
Оценка:
Здравствуйте, Lorenzo_LAMAS, Вы писали:

L_L>Есть выражение а + 2; Если а — указатель, ссылка на указатель, массив, ссылка на массив — все ок. Если а


L_L>
L_L>class A
L_L>{
L_L>public:
L_L>    operator int *();
L_L>};

L_L>void g()
L_L>{
L_L>   A a;
L_L>   a + 2;
L_L>}
L_L>


L_L>То тоже все нормально. Но почему в таком случае возникают проблемы?

L_L>
L_L>class A
L_L>{
L_L>public:
L_L>    typedef int (&RARR_t)[2];
L_L>    operator RARR_t();
L_L>};

L_L>void g()
L_L>{
L_L>   A a;
L_L>   a + 2;
L_L>}
L_L>


L_L>Комо онлайн такое не компилирует. VC 7.1 — все ок.


Имхо, потому что во втором случае требуется 2 преобразования — сначала в ссылку на массив, а потом массив в указатель (то самое преобразование, о котором очень не любит уважаемый Лаптев ), которому уже будет применяться +.
Во всех остальных случаях у тебя сразу участвует либо указатель (как в первом варианте класса А), либо то, что за один шаг к нему приводится (то, что ты написал в первой строчке)
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re[2]: оператор '+' для указателей
От: Lorenzo_LAMAS  
Дата: 24.05.04 07:56
Оценка:
J>Имхо, потому что во втором случае требуется 2 преобразования — сначала в ссылку на массив, а потом массив в указатель (то самое преобразование, о котором очень не любит уважаемый Лаптев ), которому уже будет применяться +.
J>Во всех остальных случаях у тебя сразу участвует либо указатель (как в первом варианте класса А), либо то, что за один шаг к нему приводится (то, что ты написал в первой строчке)

Не стану говорить всякие банальности типа г++ (3.2.3) компилит и т.д.
Можно, как мне кажется, придумать похожий пример, где будет встроенный оператор, будет применяться сначала пользовательское преобразование, а потом стандартное и ведь будет же работать?

class A
{
public:
    operator int();
}a;

void g()
{
   a + 2.; 
}


Вот такое можно ведь считать аналогичным?
Of course, the code must be complete enough to compile and link.
Re[3]: оператор '+' для указателей
От: Кодт Россия  
Дата: 24.05.04 08:21
Оценка:
Здравствуйте, Lorenzo_LAMAS, Вы писали:

L_L>Не стану говорить всякие банальности типа г++ (3.2.3) компилит и т.д.

L_L>Можно, как мне кажется, придумать похожий пример, где будет встроенный оператор, будет применяться сначала пользовательское преобразование, а потом стандартное и ведь будет же работать?
L_L>
L_L>class A
L_L>{
L_L>public:
L_L>    operator int();
L_L>}a;

L_L>void g()
L_L>{
L_L>   a + 2.; 
L_L>}
L_L>


L_L>Вот такое можно ведь считать аналогичным?


Имхо, нельзя: у встроенного оператора + есть сигнатуры (int,int), (int,double), (double,int), (double,double).
Вот если бы ты написал
g()
{
  A a;
  std::string s;
  s + a; // string::operator+(char)
}

то уже была бы конверсия...
Перекуём баги на фичи!
Re[3]: оператор '+' для указателей
От: jazzer Россия Skype: enerjazzer
Дата: 24.05.04 08:27
Оценка:
Здравствуйте, Lorenzo_LAMAS, Вы писали:

J>>Имхо, потому что во втором случае требуется 2 преобразования — сначала в ссылку на массив, а потом массив в указатель (то самое преобразование, о котором очень не любит уважаемый Лаптев ), которому уже будет применяться +.

J>>Во всех остальных случаях у тебя сразу участвует либо указатель (как в первом варианте класса А), либо то, что за один шаг к нему приводится (то, что ты написал в первой строчке)

L_L>Не стану говорить всякие банальности типа г++ (3.2.3) компилит и т.д.

L_L>Можно, как мне кажется, придумать похожий пример, где будет встроенный оператор, будет применяться сначала пользовательское преобразование, а потом стандартное и ведь будет же работать?

L_L>
L_L>class A
L_L>{
L_L>public:
L_L>    operator int();
L_L>}a;

L_L>void g()
L_L>{
L_L>   a + 2.; 
L_L>}
L_L>


L_L>Вот такое можно ведь считать аналогичным?


Плохой пример — здесь, помимо обычных правил разрешения перегружки, работает другое правило: после твоего преобразования к int компилятор имеет бинарный оператор, у которого оба типа — арифметические, и он исполняет для них соответствующее правило 5/9.

В первом же твоем примере у тебя не получалось арифметических типов, так что это правило не срабатывало и работали только обычные правила разрешения перегрузки.
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re[4]: оператор '+' для указателей
От: jazzer Россия Skype: enerjazzer
Дата: 24.05.04 08:31
Оценка:
Здравствуйте, Кодт, Вы писали:

К>у встроенного оператора + есть сигнатуры (int,int), (int,double), (double,int), (double,double).


Ты не прав, есть еще много других сигнатур — см. 5/9.

Вернее, тут вообще нет сигнатур (иначе они будут создавать двусмысленность в соотнесении их с 5/9), есть только 5/9.
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re[4]: оператор '+' для указателей
От: Lorenzo_LAMAS  
Дата: 24.05.04 08:55
Оценка:
Пример мне не кажется ни плохим, ни хорошим, фиг с ним. По-моему, это глюк ЕДГ.
Of course, the code must be complete enough to compile and link.
Re[5]: оператор '+' для указателей
От: jazzer Россия Skype: enerjazzer
Дата: 24.05.04 08:56
Оценка: 2 (1)
Здравствуйте, Lorenzo_LAMAS, Вы писали:

L_L>Пример мне не кажется ни плохим, ни хорошим, фиг с ним. По-моему, это глюк ЕДГ.


в сымсле, ты не согласен с моей аргументацией?

P.S. А что за ошибку комо пишет-то?
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re[6]: оператор '+' для указателей
От: Lorenzo_LAMAS  
Дата: 24.05.04 09:00
Оценка:
J>в сымсле, ты не согласен с моей аргументацией?

Я просто пока не догнал

J>P.S. А что за ошибку комо пишет-то?


Не нашел оператор + c параметрами типа А, int.
Аналогично ругаются icc, icl, bccx, ti
Of course, the code must be complete enough to compile and link.
Re[7]: оператор '+' для указателей
От: jazzer Россия Skype: enerjazzer
Дата: 24.05.04 09:51
Оценка: 10 (1)
Здравствуйте, Lorenzo_LAMAS, Вы писали:

J>>в сымсле, ты не согласен с моей аргументацией?


L_L>Я просто пока не догнал :))


Ну смотри
Вот компилятор видит твое a+i.
первым делом он, естественно, пытается найти оператор+, принимающий А и int. Не находит.
Тогда он пытается сторговаться на встроенных операторах, используя для этого не более чем одно неявное преобразование каждого операнда.
У нас встроенных операторов всего 2 типа:
1. оба операнда — арифметические
2. один операнд — целый, второй — указатель.

в случае, когда А:
* указатель — все понятно, сразу попадаем в пункт 2.
* ссылка на указатель — неявное преобразование к rvalue, пункт 2
* массив, ссылка на массив — неявное преобразование к указателю, пункт 2
* класс с operator int*() — неявное пользовательское преобразование, пункт 2.
* класс с operator RARR_t() — неявное пользовательское преобразование, не хватает еще одного преобразования к указателю — не компилируем
* класс с operator int(), а i имеет тип float — неявное пользовательское преобразование, попадаем в пункт 1.

В последнем случае, раз уж мы попали на встроенный бинарный оператор для арифметических типов, и типы эти — int и float, мы пользуемся правилом 5/9 для определения типа всего выражения (float) и приведения аргумента int к float.
То, что мы когда-то неявно накатили на a пользовательское преобразование к int, здесь уже никакой роли не играет.

J>>P.S. А что за ошибку комо пишет-то?


L_L>Не нашел оператор + c параметрами типа А, int.

L_L>Аналогично ругаются icc, icl, bccx, ti :)
ну у них же вроде edg-шный front-end :)
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.