Re[11]: Великий и могучий
От: Lorenzo_LAMAS  
Дата: 09.12.03 09:05
Оценка:
A>Это очень скверно. Позволяет ненароком снять константность.

Поясните плиз. И как я уже сказал, это VC (7.0/6.0)выбрали вторую функцию, а comeau, g++, icc — первую. Вот байда.
Of course, the code must be complete enough to compile and link.
Re[12]: Великий и могучий
От: achp  
Дата: 09.12.03 09:14
Оценка: 10 (1)
Здравствуйте, Lorenzo_LAMAS, Вы писали:

L_L>Поясните плиз. И как я уже сказал, это VC (7.0/6.0)выбрали вторую функцию, а comeau, g++, icc — первую. Вот байда.


const char* str = "Эта строка константна?"

void f(const char*& p)
{
        // p - ссылка на неконстантный указатель на константную строку...
    p = str;
}

void g()
{
        char* s;
        f(s); // Если это допускается, то все очень плохо
        strcpy(s, "Фигушки!");
}


Или я в чем-то заблуждаюсь?
Да здравствует ИМХО!
Re[13]: Великий и могучий
От: Lorenzo_LAMAS  
Дата: 09.12.03 09:20
Оценка:
A>Или я в чем-то заблуждаюсь?

Не, такое, конечно, не допускается. Т.е. тогда понятно, почему выбирается первая функция — вторая не является подходящей. Значит VC глючит. И еще остается исходный пример с шаблоном.
Of course, the code must be complete enough to compile and link.
Re[10]: Великий и могучий
От: jazzer Россия Skype: enerjazzer
Дата: 09.12.03 09:52
Оценка:
Здравствуйте, Lorenzo_LAMAS, Вы писали:

ПК>>>> не так, и шаблон является лучшим кандидатом — надо будет копнуть поглубже, как только будет время.



L_L>
L_L>void fun(const int *);
L_L>void fun(const int * &);

L_L>void g()
L_L>{
L_L>    int * p = 0;
L_L>    fun(p);
L_L>}
L_L>


L_L>Черт, никакая медитация не помогает понять, в чем тут дело. В одном случае — Lvalue преобразование, потом квалификация, в другом binding с добавлением квалификации. Почему воторое лучше первого?


второе вообще нельзя — это все равно, что внесение const под двойной указатель 4.4/4
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[11]: Великий и могучий
От: Lorenzo_LAMAS  
Дата: 09.12.03 09:53
Оценка:
J>второе вообще нельзя — это все равно, что внесение const под двойной указатель 4.4/4

Ну, VC это можно.
Of course, the code must be complete enough to compile and link.
Re[9]: Перегрузить <<
От: jazzer Россия Skype: enerjazzer
Дата: 09.12.03 09:53
Оценка:
Здравствуйте, Павел Кузнецов, Вы писали:

ПК>Здравствуйте, jazzer, Вы писали:


j>>>> насколько я понимаю, тут срабатывает преобразование char * -> char * const &, а не char * -> const char *


ПК>>> Похоже на то, но и я, и прошлая версия Comeau думали, что "обычная" функция (не шаблон) "выигрывала",

ПК>>> т.к. соответствующее преобразование имело тот же ранг (Exact Match). Судя по всему, это, все-таки,
ПК>>> не так, и шаблон является лучшим кандидатом — надо будет копнуть поглубже, как только будет время.

j>> для нешаблонной функции надо ведь еще преобразование lvalue to rvalue,

j>> а для шаблонной — только навесить квалификатор

ПК>Это все преобразования ранга Exact Match; здесь есть что-то еще.


Может, просто цепочка длиннее ? :)
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[14]: Великий и могучий
От: achp  
Дата: 09.12.03 09:58
Оценка:
Здравствуйте, Lorenzo_LAMAS, Вы писали:

A>>Или я в чем-то заблуждаюсь?


L_L>Не, такое, конечно, не допускается.


Что языком не допускается, это ясно. Я про компилятор. Очень это печально слышать, прийдется быть осторожнее.
Да здравствует ИМХО!
Re[15]: Великий и могучий
От: Lorenzo_LAMAS  
Дата: 09.12.03 10:03
Оценка:
A>Что языком не допускается, это ясно. Я про компилятор. Очень это печально слышать, прийдется быть осторожнее.

Все началось с того, что меня переклинило и template<class T>void fun(const T &) для случая char * c = 0; я истолковал как fun(const char * &); — и соответственно такое и написал (нешаблонную функцию). Оба вижуала преспокойно вызвали эту функцию, хотя так же хулиганить с многоуровневыми указателяит они не дадут.
Of course, the code must be complete enough to compile and link.
Re[16]: Великий и могучий
От: achp  
Дата: 09.12.03 10:21
Оценка: :)
Здравствуйте, Lorenzo_LAMAS, Вы писали:

L_L>Все началось с того, что меня переклинило


Уф! Ну, слава богу!
Да здравствует ИМХО!
Re[8]: Перегрузить <<
От: Павел Кузнецов  
Дата: 10.12.03 08:55
Оценка:
Здравствуйте, Шахтер, Вы писали:

Ш> — Standard conversion sequence S1 is a better conversion sequence than standard conversion sequence

Ш> S2 if <...>
Ш> — S1 and S2 differ only in their qualification conversion and yield similar types T1 and T2 (4.4),
Ш> respectively, and the cvqualification
Ш> signature of type T1 is a proper subset of the cvqualification
Ш> signature of type T2, [Example:
Ш> int f(const int *);
Ш> int f(int *);
Ш> int i;
Ш> int j = f(&i); // Calls f(int *)
Ш> —end example] or, if not that,
Ш>


Очень похоже на то! Спасибо.
Posted via RSDN NNTP Server 1.7 "Bedlam"
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Re[9]: Перегрузить <<
От: Аноним  
Дата: 10.12.03 09:13
Оценка:
Ну и чья же квалификация сабсетом чьей тут является?
Re[10]: Перегрузить <<
От: Павел Кузнецов  
Дата: 10.12.03 12:17
Оценка:
Здравствуйте, Вы писали:

> Ну и чья же квалификация сабсетом чьей тут является?


Та да... Здесь, действительно, получается const int* vs. int* const&,
а не const int* vs. int*. Ладно... Надо будет раскопать этот случай
как-нибудь на досуге. Или еще лучше, дождаться, пока кто-нибудь раскопает
Posted via RSDN NNTP Server 1.7 "Bedlam"
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Re[11]: Перегрузить <<
От: Аноним  
Дата: 10.12.03 12:27
Оценка:
Ой Павел, ой насмешил! Зря я анонимно писал Боялся опозориться, как это теперь особенно часто со мной бывает
Re[12]: Перегрузить <<
От: Павел Кузнецов  
Дата: 10.12.03 13:52
Оценка:
Здравствуйте, Вы писали:

> Ой Павел, ой насмешил! Зря я анонимно писал

> Боялся опозориться, как это теперь особенно часто со мной бывает

Чем именно насмешил?.. Ничего не понял...
Posted via RSDN NNTP Server 1.7 "Bedlam"
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Re[13]: Перегрузить <<
От: Аноним  
Дата: 10.12.03 14:05
Оценка:
ПК>Чем именно насмешил?.. Ничего не понял...

Ну типа словами "пусть другие найдут"
Re[14]: Перегрузить <<
От: Павел Кузнецов  
Дата: 10.12.03 14:36
Оценка:
Здравствуйте, Вы писали:

ПК>> Чем именно насмешил?.. Ничего не понял...


> Ну типа словами "пусть другие найдут"


У меня сейчас такой цейтнот, что разбираться просто некогда

Но получить ответ уже очень интересно Вот и надеюсь, что кто-нибудь
соберется с духом раньше меня.
Posted via RSDN NNTP Server 1.7 "Bedlam"
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Re[15]: Перегрузить <<
От: Аноним  
Дата: 10.12.03 14:51
Оценка: :)
Там небось как назло делов на 10 мин. медитирования-то
Re[9]: Перегрузить <<
От: Шахтер Интернет  
Дата: 29.05.04 19:54
Оценка:
Здравствуйте, Павел Кузнецов, Вы писали:

ПК>Здравствуйте, Lorenzo_LAMAS, Вы писали:


LL>> Подождите, что-то я не догоняю. Есть две функции, одна принимает const char *, другая шаблон

LL>> и принимает const T &. "число" имеет тип const char[6]. Разве ж для него не должна вызваться
LL>> шаблонная функция? Ведь для нее не нужно никаких преобразований?

ПК>Array-to-pointer имеет ранг Exact Match, поэтому с точки зрения перегрузки эти две функции равны.


Нет, не равны.

/* main.cpp */ 

#include <iostream>

using namespace std;

/* main() */ 

void test(const char * &) { cout << "1\n" ; }

void test(char * &) { cout << "2\n" ; }

void test(const char (&)[2]) { cout << "3\n" ; }

int main()
 {
  test("x");
 
  return 0;
 }


И VC++ 7.1 и Intel C++ 8.0 выбирают третий вариант. А вот стандарт. 13.3.3.2 3

— Standard conversion sequence S1 is a better conversion sequence than standard conversion sequence
S2 if

— S1 is a proper subsequence of S2 (comparing the conversion sequences in the canonical form
defined by 13.3.3.1.1, excluding any Lvalue Transformation; the identity conversion sequence is
considered to be a subsequence of any nonidentity
conversion sequence
) or, if not that,


Связывение со ссылкой и есть это identity conversion, чуть выше 13.3.3.1.4

When a parameter of reference type binds directly (8.5.3) to an argument expression, the implicit conversion
sequence is the identity conversion, unless the argument expression has a type that is a derived class of
the parameter type, in which case the implicit conversion sequence is a derived to base
Conversion.

... << RSDN@Home 1.1.0 stable >>
В XXI век с CCore.
Копай Нео, копай -- летать научишься. © Matrix. Парадоксы
Re[10]: Перегрузить <<
От: Павел Кузнецов  
Дата: 30.05.04 03:50
Оценка:
> LL>> Есть две функции, одна принимает const char *, другая шаблон и принимает const T &. "число" имеет тип const char[6]. Разве ж для него не должна вызваться шаблонная функция? Ведь для нее не нужно никаких преобразований?

> ПК>Array-to-pointer имеет ранг Exact Match, поэтому с точки зрения перегрузки эти две функции равны.


> Нет, не равны.

>
>
> void test(const char * &) { cout << "1\n" ; }
>
> void test(char * &) { cout << "2\n" ; }
>
> void test(const char (&)[2]) { cout << "3\n" ; }
>
> int main()
>  {
>   test("x");
>


Это совсем другой пример. В данном случае первые две функции принимают char* — одна по константной ссылке, другая — по неконстантной. Очевидно, что строковый литерал к char* преобразован быть не может. Соответственно, никакого выбора лучшего кандидата здесь не наблюдается: подходит только последний вариант. Чтобы убедиться в этом, просто закомментируй его.

Случаю, описанному Lorenzo_LAMAS, соответствует такие сигнатуры:
void test(const char *);
void test(const char (&)[2]);

Или, если тебе нравятся ссылки, то так:
void test(char const *&);
void test(const char (&)[2]);

В обоих случаях компилятор выбрать лучшую функцию не сможет. Именно потому что и у identity conversion, и у array-to-pointer conversion один и тот же ранг — Exact Match (13.3.3.1.1, таблица 9), и ни одна из этих последовательностей не является подпоследовательностью другой, т.к. Lvalue Transformations не учитываются при сравнении преобразований.

> А вот стандарт. 13.3.3.2 3


Очень кстати Я позволю себе изменить выделение в приведенной цитате, чтобы было лучше видно:

>

> — S1 is a proper subsequence of S2 (comparing the conversion sequences in the canonical form defined by 13.3.3.1.1, excluding any Lvalue Transformation; the identity conversion sequence is considered to be a subsequence of any nonidentity conversion sequence) or, if not that,


array-to-pointer conversion и является разновидностью Lvalue Transformation (все та же таблица 9). Соответственно, исключая эту часть преобразования, получим ту же identity conversion, которая ничуть не хуже привязывания ссылки.
Posted via RSDN NNTP Server 1.9 alpha
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Re[11]: Перегрузить <<
От: Шахтер Интернет  
Дата: 30.05.04 05:28
Оценка:
Здравствуйте, Павел Кузнецов, Вы писали:

Ага. Всё дело в волшебных пузырьках.

ПК>Случаю, описанному Lorenzo_LAMAS, соответствует такие сигнатуры:

ПК>
ПК>void test(const char *);
ПК>void test(const char (&)[2]);
ПК>


Здесь ambiguty.

ПК>Или, если тебе нравятся ссылки, то так:

ПК>
ПК>void test(char const *&);
ПК>void test(const char (&)[2]);
ПК>


А вот здесь нет ambiguty.

Вот здесь ambiguty.

void test(const char (&)[2]);

void test(const char *const &);


ПК>В обоих случаях компилятор выбрать лучшую функцию не сможет.
... << RSDN@Home 1.1.0 stable >>
В XXI век с CCore.
Копай Нео, копай -- летать научишься. © Matrix. Парадоксы
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.