Или ты подразумеваешь проблемы какого-нибудь конкретного компилятора? Опять же, почему тогда не добавлены перегруженные версии для всех арифметических типов, ведь с ними будут те же "проблемы"?
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Здравствуйте, Павел Кузнецов, Вы писали:
ПК>Здравствуйте, Шахтер, Вы писали:
ПК>>>А зачем обе версии: и operator << (char *x), и operator << (const char *x)?
ПК>Например, следующая программа: ПК>
ПК>безо всяких фокусов.
ПК>Или ты подразумеваешь проблемы какого-нибудь конкретного компилятора? Опять же, почему тогда не добавлены перегруженные версии для всех арифметических типов, ведь с ними будут те же "проблемы"?
Насчет должна не знаю, мне влом заниматься очередным исследованием стандарта. Да и написать лишнюю строчку, чтобы компилятор не напрягал мозги -- не большая проблема.
Вот выход VC++ 7.1
operator << (const char *)
operator << (int)
operator << (const T&)
Press any key to continue
Насчет арифметических типов -- верно, надо их всех перегрузить. Чтобы не увеличивать объём кода, надо определить семейство базовых функций форматирования
void put(const char *);
void put(int);
void put(unsigned int);
void put(long long); // или __int64
void put(unsigned long long); // или unsigned __int64
А в соответствующих операторах вызывать подходящие версии put.
Здравствуйте, Шахтер, Вы писали:
ПК>>>> А зачем обе версии: и operator << (char *x), и operator << (const char *x)?
ПК>> Например, следующая программа: <...> должна печатать: ПК>>
ПК>> безо всяких фокусов.
Ш> Насчет должна не знаю, мне влом заниматься очередным исследованием стандарта.
Похоже, не так уж и должна. Похоже мы с Comeau немного ошиблись: его новая версия ведет
себя так же, как VC++7.1, и свежий GCC.
ПК>> Опять же, почему тогда не добавлены перегруженные версии для всех арифметических ПК>> типов, ведь с ними будут те же "проблемы"?
Ш> Насчет арифметических типов -- верно, надо их всех перегрузить.
По-моему, лучше просто лишний раз не заморачиваться с шаблоном operator <<
Но если, все-таки, подразумевалось делегирование << стандартному потоку, придется
еще и operator << для манипуляторов предоставить...
Posted via RSDN NNTP Server 1.7 "Bedlam"
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Подождите, что-то я не догоняю. Есть две функции, одна принимает const char *, другая шаблон и принимает const T &. "число" имеет тип const char[6]. Разве ж для него не должна вызваться шаблонная функция? Ведь для нее не нужно никаких преобразований?
Of course, the code must be complete enough to compile and link.
Здравствуйте, Павел Кузнецов, Вы писали:
ПК>Здравствуйте, Шахтер, Вы писали:
ПК>>>А зачем обе версии: и operator << (char *x), и operator << (const char *x)? :???:
Ш>>Затем, что если ещё добавить
Ш>>
ПК>безо всяких фокусов.
ПК>Или ты подразумеваешь проблемы какого-нибудь конкретного компилятора? Опять же, почему тогда не добавлены перегруженные версии для всех арифметических типов, ведь с ними будут те же "проблемы"?
насколько я понимаю, тут срабатывает преобразование char * -> char * const &, а не char * -> const char *
ПК>> безо всяких фокусов.
j> насколько я понимаю, тут срабатывает преобразование char * -> char * const &, а не char * -> const char *
Похоже на то, но и я, и прошлая версия Comeau думали, что "обычная" функция (не шаблон) "выигрывала",
т.к. соответствующее преобразование имело тот же ранг (Exact Match). Судя по всему, это, все-таки,
не так, и шаблон является лучшим кандидатом — надо будет копнуть поглубже, как только будет время.
Posted via RSDN NNTP Server 1.7 "Bedlam"
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
ПК>>> безо всяких фокусов.
j>> насколько я понимаю, тут срабатывает преобразование char * -> char * const &, а не char * -> const char *
ПК>Похоже на то, но и я, и прошлая версия Comeau думали, что "обычная" функция (не шаблон) "выигрывала", ПК>т.к. соответствующее преобразование имело тот же ранг (Exact Match). Судя по всему, это, все-таки, ПК>не так, и шаблон является лучшим кандидатом — надо будет копнуть поглубже, как только будет время.
для нешаблонной функции надо ведь еще преобразование lvalue to rvalue, а для шаблонной — только навесить квалификатор
Здравствуйте, Lorenzo_LAMAS, Вы писали:
LL> Подождите, что-то я не догоняю. Есть две функции, одна принимает const char *, другая шаблон LL> и принимает const T &. "число" имеет тип const char[6]. Разве ж для него не должна вызваться LL> шаблонная функция? Ведь для нее не нужно никаких преобразований?
Array-to-pointer имеет ранг Exact Match, поэтому с точки зрения перегрузки эти две функции равны. Например:
"ComeauTest.c", line 6: error: more than one instance of overloaded function "f"
matches the argument list, the choices that match are:
function "f(const char *)"
function "f(const char (&)[6])"
The argument types that you used are: (const char [6])
f("число");
^
В случае же когда одна из этих функций является специализацией шаблона, вторая "выигрывает", т.к.,
грубо говоря, при прочих равных, "обычные" функции (не шаблоны) имеют преимущество перед шаблонами.
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Здравствуйте, jazzer, Вы писали:
j>>> насколько я понимаю, тут срабатывает преобразование char * -> char * const &, а не char * -> const char *
ПК>> Похоже на то, но и я, и прошлая версия Comeau думали, что "обычная" функция (не шаблон) "выигрывала", ПК>> т.к. соответствующее преобразование имело тот же ранг (Exact Match). Судя по всему, это, все-таки, ПК>> не так, и шаблон является лучшим кандидатом — надо будет копнуть поглубже, как только будет время.
j> для нешаблонной функции надо ведь еще преобразование lvalue to rvalue, j> а для шаблонной — только навесить квалификатор
Здравствуйте, Павел Кузнецов, Вы писали:
ПК>Здравствуйте, Шахтер, Вы писали:
ПК>>>>> А зачем обе версии: и operator << (char *x), и operator << (const char *x)?
ПК>>> Например, следующая программа: <...> должна печатать: ПК>>>
ПК>>> безо всяких фокусов.
Ш>> Насчет должна не знаю, мне влом заниматься очередным исследованием стандарта.
ПК>Похоже, не так уж и должна. Похоже мы с Comeau немного ошиблись: его новая версия ведет ПК>себя так же, как VC++7.1, и свежий GCC.
Похоже, здесь. В принципе, логично, поскольку навешивание const модификатора сужает множество операций над объектом (вообще говоря, значительно).
13.3.3.2
Two implicit conversion sequences of the same form are indistinguishable conversion sequences unless one
of the following rules apply:
— 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,
— the rank of S1 is better than the rank of S2 (by the rules defined below), or, if not that,
— 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,
ПК>>> не так, и шаблон является лучшим кандидатом — надо будет копнуть поглубже, как только будет время.
void fun(const int *);
void fun(const int * &);
void g()
{
int * p = 0;
fun(p);
}
Черт, никакая медитация не помогает понять, в чем тут дело. В одном случае — Lvalue преобразование, потом квалификация, в другом binding с добавлением квалификации. Почему воторое лучше первого?
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 с добавлением квалификации. Почему воторое лучше первого?
Это очень скверно. Позволяет ненароком снять константность.