Здравствуйте, 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, "Фигушки!");
}
Не, такое, конечно, не допускается. Т.е. тогда понятно, почему выбирается первая функция — вторая не является подходящей. Значит VC глючит. И еще остается исходный пример с шаблоном.
Of course, the code must be complete enough to compile and link.
Здравствуйте, 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, Вы писали:
j>>>> насколько я понимаю, тут срабатывает преобразование char * -> char * const &, а не char * -> const char *
ПК>>> Похоже на то, но и я, и прошлая версия Comeau думали, что "обычная" функция (не шаблон) "выигрывала", ПК>>> т.к. соответствующее преобразование имело тот же ранг (Exact Match). Судя по всему, это, все-таки, ПК>>> не так, и шаблон является лучшим кандидатом — надо будет копнуть поглубже, как только будет время.
j>> для нешаблонной функции надо ведь еще преобразование lvalue to rvalue, j>> а для шаблонной — только навесить квалификатор
ПК>Это все преобразования ранга Exact Match; здесь есть что-то еще.
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.
Здравствуйте, Шахтер, Вы писали:
Ш> — 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
Оценка:
Ну и чья же квалификация сабсетом чьей тут является?
Здравствуйте, Вы писали:
> Ну и чья же квалификация сабсетом чьей тут является?
Та да... Здесь, действительно, получается const int* vs. int* const&,
а не const int* vs. int*. Ладно... Надо будет раскопать этот случай
как-нибудь на досуге. Или еще лучше, дождаться, пока кто-нибудь раскопает
Posted via RSDN NNTP Server 1.7 "Bedlam"
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Re[11]: Перегрузить <<
От:
Аноним
Дата:
10.12.03 12:27
Оценка:
Ой Павел, ой насмешил! Зря я анонимно писал Боялся опозориться, как это теперь особенно часто со мной бывает
Здравствуйте, Павел Кузнецов, Вы писали:
ПК>Здравствуйте, Lorenzo_LAMAS, Вы писали:
LL>> Подождите, что-то я не догоняю. Есть две функции, одна принимает const char *, другая шаблон LL>> и принимает const T &. "число" имеет тип const char[6]. Разве ж для него не должна вызваться LL>> шаблонная функция? Ведь для нее не нужно никаких преобразований?
ПК>Array-to-pointer имеет ранг Exact Match, поэтому с точки зрения перегрузки эти две функции равны.
И 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.
> LL>> Есть две функции, одна принимает const char *, другая шаблон и принимает const T &. "число" имеет тип const char[6]. Разве ж для него не должна вызваться шаблонная функция? Ведь для нее не нужно никаких преобразований?
> ПК>Array-to-pointer имеет ранг Exact Match, поэтому с точки зрения перегрузки эти две функции равны.
> Нет, не равны. > >
Это совсем другой пример. В данном случае первые две функции принимают char* — одна по константной ссылке, другая — по неконстантной. Очевидно, что строковый литерал к char* преобразован быть не может. Соответственно, никакого выбора лучшего кандидата здесь не наблюдается: подходит только последний вариант. Чтобы убедиться в этом, просто закомментируй его.
Случаю, описанному Lorenzo_LAMAS, соответствует такие сигнатуры:
В обоих случаях компилятор выбрать лучшую функцию не сможет. Именно потому что и у 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
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен