Re[4]: Function overloading
От: Bell Россия  
Дата: 21.12.05 13:19
Оценка:
Здравствуйте, Lorenzo_LAMAS, Вы писали:

B>>Вот здесь
Автор: Lorenzo_LAMAS
Дата: 21.08.03
все описано очень подробно.


L_L>Т.е. ты из этого объяснения, применив его к текущему примеру все понял?


Ну да
Кроме того, сделал для себя открытие:
class A
{
};

class B : public A // (*)
{
};

class Test
{
public:
   operator A() const;
   operator B();
};

void fun(A)
{
}

int main ()
{
   Test t;
   fun(t);
   return 0;
}


Вчера я бы сказал, что при вызове fun будет использован Test::operator A, т.е. цепочка преобразований будет такой: Test -> const Test -> A. Согласно же объяснению ПК, цепочка Test -> B -> A лучше. Проверил на VC7.1 и на VC6 — действительно, вызывается Test::operator B
Любите книгу — источник знаний (с) М.Горький
Re[5]: Function overloading
От: Lorenzo_LAMAS  
Дата: 21.12.05 13:32
Оценка:
Я чего-то туплю и простейших вещей не догоняю. Читать главу 13 тяжко и лениво . Не пояснишь такого (извини, что требую, по сути, объяснения объясненного):
class A{};
class B : public A{};

void fun(A *){}
void fun(B *){}

class Test {
public:
   operator A*()const{return 0;}
   operator B*(){return 0;}
};

int main()
{
   Test t;
   fun(t);
}


Тут вроде моего скудоумия хватает чтоб понять. Для fun(A *) есть две цепочки (с одинаковым рангом), одна из них лучше, так как в другой добавляется const(*). Для fun(B *) подходит только одна, и теперь есть
fun(A*) Test->B*->A*
fun(B*) Test->B*


и вторая лучше, так как она — часть первой.
Теперь, меняем местами const.
Для fun(A*) лучше начинает подходить Test->A*
Для fun(B*) подходит только Test->const Test &->B*

Здесь неоднозначность. Я вот чего не пойму, если в случае (*) наличие const позволило сделать выбор, то почему здесь нельзя так же?
Of course, the code must be complete enough to compile and link.
Re[6]: Function overloading
От: Bell Россия  
Дата: 21.12.05 14:54
Оценка: 2 (1)
Здравствуйте, Lorenzo_LAMAS, Вы писали:

L_L>Я чего-то туплю и простейших вещей не догоняю. Читать главу 13 тяжко и лениво . Не пояснишь такого (извини, что требую, по сути, объяснения объясненного):

L_L>
L_L>class A{};
L_L>class B : public A{};

L_L>void fun(A *){}
L_L>void fun(B *){}

L_L>class Test {
L_L>public:
L_L>   operator A*()const{return 0;}
L_L>   operator B*(){return 0;}
L_L>};

L_L>int main()
L_L>{
L_L>   Test t;
L_L>   fun(t);
L_L>}
L_L>


L_L>Тут вроде моего скудоумия хватает чтоб понять. Для fun(A *) есть две цепочки (с одинаковым рангом), одна из них лучше, так как в другой добавляется const(*). Для fun(B *) подходит только одна, и теперь есть

L_L>
L_L>fun(A*) Test->B*->A*
L_L>fun(B*) Test->B*
L_L>


L_L>и вторая лучше, так как она — часть первой.

L_L>Теперь, меняем местами const.
L_L>Для fun(A*) лучше начинает подходить Test->A*
L_L>Для fun(B*) подходит только Test->const Test &->B*

L_L>Здесь неоднозначность. Я вот чего не пойму, если в случае (*) наличие const позволило сделать выбор, то почему здесь нельзя так же?


Ты заставил меня засомневаться
Тем не менее попробую объяснить свое вИдение:
Итак, имеется 2 функции-кандидата fun. Сначала для каждой из этих функций определяется лучшая цепочка преобразований (если их несколько), при этом в нашем случае рассматривается только первая цепочка стандартных преобразований. Из-за этого во втором случае цепочка Test -> const Test -> B* -> A* отбрасывается. В результате для fun(A*) получаем цепочку Test -> A* с использованием Test::operator A*, а для fun(B*) — цепочку Test -> const Test -> B*, но уже с использованием Test::operator B*. Далее смотрим 13.3.3.2/3

...
User-defined conversion sequence U1 is a better conversion sequence than 
another user-defined conversion sequence U2 if they contain the same 
user-defined conversion function or constructor and if the second standard 
conversion sequence of U1 is better than the second standard conversion sequence of U2.
...


поскольку у нас используются 2 различных conversion functions, то различить последовательности невозможно...
А вот в оригинальном примере у нас было 2 user-defined последовательности с одной conversion function...
Любите книгу — источник знаний (с) М.Горький
Re[7]: Function overloading
От: Lorenzo_LAMAS  
Дата: 21.12.05 15:05
Оценка:
>поскольку у нас используются 2 различных conversion functions, то различить последовательности невозможно...
>А вот в оригинальном примере у нас было 2 user-defined последовательности с одной conversion function...

Ну а если есть fun(A*) и Test->const Test &->A * и Test->B * -> A* то тут-то различить можно?

>Сначала для каждой из этих функций определяется лучшая цепочка преобразований (если их несколько), при этом в нашем >случае рассматривается только первая цепочка стандартных преобразований. Из-за этого во втором случае цепочка Test ->> const Test -> B* -> A* отбрасывается.


Из-за чего "из-за этого" ? Поясни причинно следственность
Of course, the code must be complete enough to compile and link.
Re[8]: Function overloading
От: Bell Россия  
Дата: 21.12.05 15:28
Оценка: 1 (1) +1
Здравствуйте, Lorenzo_LAMAS, Вы писали:

>>поскольку у нас используются 2 различных conversion functions, то различить последовательности невозможно...

>>А вот в оригинальном примере у нас было 2 user-defined последовательности с одной conversion function...

L_L>Ну а если есть fun(A*) и Test->const Test &->A * и Test->B * -> A* то тут-то различить можно?

Нет — в этих цепочках 2 различные функции преобразования — Test::operator A* и Test::operator B*


>>Сначала для каждой из этих функций определяется лучшая цепочка преобразований (если их несколько), при этом в нашем >случае рассматривается только первая цепочка стандартных преобразований. Из-за этого во втором случае цепочка Test -> const Test -> B* -> A* отбрасывается.


L_L>Из-за чего "из-за этого" ? Поясни причинно следственность

Так. Мы имеем дело с user-defined conversion sequence, а она
... consists of an initial standard conversion sequence followed by a
user-defined conversion (12.3) followed by a second standard conversion sequence.


Есть функция f(A*);. Есть вызов f(t). Есть 2 варианта преобразования Test -> A*:
1. Test -> A*.
2. Test -> const Test -> B* -> A*.
Соответствующие первые цепочки преобразований (initial standard conversion sequence):
1. Test
2. Test -> const Test
первая лучше, и fun(A*) ассоциируется с цепочкой Test -> A*, и в процессе поиска лучшей функции рассматривается только одна эта цепочка.
Любите книгу — источник знаний (с) М.Горький
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.