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[2]: Перегрузить <<
От: Павел Кузнецов  
Дата: 07.12.03 18:54
Оценка: +1
Здравствуйте, Шахтер, Вы писали:

Ш>
Ш>class CFoo
Ш>{
Ш> ...
Ш> CFoo & operator << (int x) { ... return *this; }
Ш> CFoo & operator << (char *x) { ... return *this; }
Ш> CFoo & operator << (const char *x) { ... return *this; }
Ш> ...
Ш>};
Ш>


А зачем обе версии: и operator << (char *x), и operator << (const char *x)?
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Re[16]: Великий и могучий
От: achp  
Дата: 09.12.03 10:21
Оценка: :)
Здравствуйте, Lorenzo_LAMAS, Вы писали:

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


Уф! Ну, слава богу!
Да здравствует ИМХО!
Re[15]: Перегрузить <<
От: Аноним  
Дата: 10.12.03 14:51
Оценка: :)
Там небось как назло делов на 10 мин. медитирования-то
Перегрузить <<
От: Аноним  
Дата: 07.12.03 12:38
Оценка:
Добрый день!

Как мне перегрузть оператор << в классе, что бы можно было делать так:

class CFoo
{
 ...
 void operator <<(???) {???}
 ...
};
CFoo f;
f << "Число" << 5 ;


Спасибо.
Re: Перегрузить <<
От: Alxndr Германия http://www.google.com/profiles/alexander.poluektov#buzz
Дата: 07.12.03 13:21
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Как мне перегрузть оператор << в классе, что бы можно было делать так:


А>
А>class CFoo
А>{
А> ...
А> CFoo& operator <<(int i) {/* здесь логика перегрузки */}
А> ...
А>};
А>CFoo f;
А>f << "Число" << 5 ;
А>


Исправлено по просьбе автора. -- ПК
Re[2]: Перегрузить <<
От: Аноним  
Дата: 07.12.03 17:39
Оценка:
Здравствуйте, Alxndr, Вы писали:

А>>
А>>class CFoo
А>>{
А>> ...
А>> f& operator <<(int i) {/* здесь логика перегрузки */}
А>> ...
А>>};
А>>CFoo f;
А>>f << "Число" << 5 ;
А>>


Не понял — можешь разъяснить...
Re: Перегрузить <<
От: Шахтер Интернет  
Дата: 07.12.03 18:18
Оценка:
Здравствуйте, <Аноним>, Вы писали:

А>Добрый день!


А>Как мне перегрузть оператор << в классе, что бы можно было делать так:


А>
А>class CFoo
А>{
А> ...
А> void operator <<(???) {???}
А> ...
А>};
А>CFoo f;
А>f << "Число" << 5 ;
А>


А>Спасибо.


class CFoo
{
 ...
 CFoo & operator << (int x) { ... return *this; }
 CFoo & operator << (char *x) { ... return *this; }
 CFoo & operator << (const char *x) { ... return *this; }
 ...
};
CFoo f;
f << "Число" << 5 ;
... << RSDN@Home 1.1.0 stable >>
В XXI век с CCore.
Копай Нео, копай -- летать научишься. © Matrix. Парадоксы
Re[3]: Перегрузить <<
От: Шахтер Интернет  
Дата: 07.12.03 19:24
Оценка:
Здравствуйте, Павел Кузнецов, Вы писали:

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


Ш>>
Ш>>class CFoo
Ш>>{
Ш>> ...
Ш>> CFoo & operator << (int x) { ... return *this; }
Ш>> CFoo & operator << (char *x) { ... return *this; }
Ш>> CFoo & operator << (const char *x) { ... return *this; }
Ш>> ...
Ш>>};
Ш>>


ПК>А зачем обе версии: и operator << (char *x), и operator << (const char *x)?


Затем, что если ещё добавить

template <class T>
CFoo & operator << (const T &x) { ... return *this; }


то начнутся проблемы.
... << RSDN@Home 1.1.0 stable >>
В XXI век с CCore.
Копай Нео, копай -- летать научишься. © Matrix. Парадоксы
Re[4]: Перегрузить <<
От: Павел Кузнецов  
Дата: 07.12.03 19:46
Оценка:
Здравствуйте, Шахтер, Вы писали:

ПК>>А зачем обе версии: и operator << (char *x), и operator << (const char *x)?


Ш>Затем, что если ещё добавить


Ш>
Ш>template <class T>
Ш>CFoo & operator << (const T &x) { ... return *this; }
Ш>


Ш>то начнутся проблемы.


Хм... Какие?

Например, следующая программа:
#include <iostream>

class CFoo
{
public:
 CFoo & operator << (int x) {
   std::cout << "operator << (int)" << std::endl;
   return *this; }

 CFoo & operator << (const char *x)  {
   std::cout << "operator << (const char *)" << std::endl;
   return *this; }

 template<class T>
 CFoo & operator << (const T&) {
   std::cout << "operator << (const T&)" << std::endl;
   return *this; }
};

int main()
{
  CFoo f;
  f << "Число" << 5 ;

  char* c = 0;
  f << c;
}

должна печатать:
operator << (const char *)
operator << (int)
operator << (const char *)

безо всяких фокусов.

Или ты подразумеваешь проблемы какого-нибудь конкретного компилятора? Опять же, почему тогда не добавлены перегруженные версии для всех арифметических типов, ведь с ними будут те же "проблемы"?
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Re[5]: Перегрузить <<
От: Шахтер Интернет  
Дата: 07.12.03 20:11
Оценка:
Здравствуйте, Павел Кузнецов, Вы писали:

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


ПК>>>А зачем обе версии: и operator << (char *x), и operator << (const char *x)?


ПК>Например, следующая программа:

ПК>
ПК>#include <iostream>

ПК>class CFoo
ПК>{
ПК>public:
ПК> CFoo & operator << (int x) {
ПК>   std::cout << "operator << (int)" << std::endl;
ПК>   return *this; }

ПК> CFoo & operator << (const char *x)  {
ПК>   std::cout << "operator << (const char *)" << std::endl;
ПК>   return *this; }

ПК> template<class T>
ПК> CFoo & operator << (const T&) {
ПК>   std::cout << "operator << (const T&)" << std::endl;
ПК>   return *this; }
ПК>};

ПК>int main()
ПК>{
ПК>  CFoo f;
ПК>  f << "Число" << 5 ;

ПК>  char* c = 0;
ПК>  f << c;
ПК>}
ПК>

ПК>должна печатать:
ПК>
ПК>operator << (const char *)
ПК>operator << (int)
ПК>operator << (const char *)
ПК>

ПК>безо всяких фокусов.

ПК>Или ты подразумеваешь проблемы какого-нибудь конкретного компилятора? Опять же, почему тогда не добавлены перегруженные версии для всех арифметических типов, ведь с ними будут те же "проблемы"?


Насчет должна не знаю, мне влом заниматься очередным исследованием стандарта. Да и написать лишнюю строчку, чтобы компилятор не напрягал мозги -- не большая проблема.
Вот выход 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.
... << RSDN@Home 1.1.0 stable >>
В XXI век с CCore.
Копай Нео, копай -- летать научишься. © Matrix. Парадоксы
Re[6]: Перегрузить <<
От: Павел Кузнецов  
Дата: 08.12.03 09:57
Оценка:
Здравствуйте, Шахтер, Вы писали:

ПК>>>> А зачем обе версии: и operator << (char *x), и operator << (const char *x)?


ПК>> Например, следующая программа: <...> должна печатать:

ПК>>
 ПК>> operator << (const char *)
 ПК>> operator << (int)
 ПК>> operator << (const char *)
 ПК>>

ПК>> безо всяких фокусов.

Ш> Насчет должна не знаю, мне влом заниматься очередным исследованием стандарта.


Похоже, не так уж и должна. Похоже мы с Comeau немного ошиблись: его новая версия ведет
себя так же, как VC++7.1, и свежий GCC.

ПК>> Опять же, почему тогда не добавлены перегруженные версии для всех арифметических

ПК>> типов, ведь с ними будут те же "проблемы"?

Ш> Насчет арифметических типов -- верно, надо их всех перегрузить.


По-моему, лучше просто лишний раз не заморачиваться с шаблоном operator <<

Но если, все-таки, подразумевалось делегирование << стандартному потоку, придется
еще и operator << для манипуляторов предоставить...
Posted via RSDN NNTP Server 1.7 "Bedlam"
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Re: Перегрузить <<
От: Lorenzo_LAMAS  
Дата: 08.12.03 10:02
Оценка:
Здравствуйте, Аноним, Вы писали:

Может, перегрузить его дважды?

class A
{
public:
   A & operator <<(const char *);
   A & operator <<(int);
};
Of course, the code must be complete enough to compile and link.
Re[7]: Перегрузить <<
От: Lorenzo_LAMAS  
Дата: 08.12.03 10:20
Оценка:
Подождите, что-то я не догоняю. Есть две функции, одна принимает const char *, другая шаблон и принимает const T &. "число" имеет тип const char[6]. Разве ж для него не должна вызваться шаблонная функция? Ведь для нее не нужно никаких преобразований?
Of course, the code must be complete enough to compile and link.
Re[5]: Перегрузить <<
От: jazzer Россия Skype: enerjazzer
Дата: 08.12.03 10:29
Оценка:
Здравствуйте, Павел Кузнецов, Вы писали:

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


ПК>>>А зачем обе версии: и operator << (char *x), и operator << (const char *x)? :???:


Ш>>Затем, что если ещё добавить


Ш>>
Ш>>template <class T>
Ш>>CFoo & operator << (const T &x) { ... return *this; }
Ш>>


Ш>>то начнутся проблемы.


ПК>Хм... Какие?


ПК>Например, следующая программа:

ПК>
ПК>#include <iostream>

ПК>class CFoo
ПК>{
ПК>public:
ПК> CFoo & operator << (int x) {
ПК>   std::cout << "operator << (int)" << std::endl;
ПК>   return *this; }

ПК> CFoo & operator << (const char *x)  {
ПК>   std::cout << "operator << (const char *)" << std::endl;
ПК>   return *this; }

ПК> template<class T>
ПК> CFoo & operator << (const T&) {
ПК>   std::cout << "operator << (const T&)" << std::endl;
ПК>   return *this; }
ПК>};

ПК>int main()
ПК>{
ПК>  CFoo f;
ПК>  f << "Число" << 5 ;

ПК>  char* c = 0;
ПК>  f << c;
ПК>}
ПК>

ПК>должна печатать:
ПК>
ПК>operator << (const char *)
ПК>operator << (int)
ПК>operator << (const char *)
ПК>

ПК>безо всяких фокусов.

ПК>Или ты подразумеваешь проблемы какого-нибудь конкретного компилятора? Опять же, почему тогда не добавлены перегруженные версии для всех арифметических типов, ведь с ними будут те же "проблемы"?


насколько я понимаю, тут срабатывает преобразование char * -> char * const &, а не char * -> const char *
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]: Перегрузить <<
От: Павел Кузнецов  
Дата: 08.12.03 11:01
Оценка:
Здравствуйте, jazzer, Вы писали:

ПК>> Например, следующая программа: <...>

ПК>> должна печатать:
ПК>>
 ПК>> operator << (const char *)
 ПК>> operator << (int)
 ПК>> operator << (const char *)
 ПК>>

ПК>> безо всяких фокусов.

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


Похоже на то, но и я, и прошлая версия Comeau думали, что "обычная" функция (не шаблон) "выигрывала",
т.к. соответствующее преобразование имело тот же ранг (Exact Match). Судя по всему, это, все-таки,
не так, и шаблон является лучшим кандидатом — надо будет копнуть поглубже, как только будет время.
Posted via RSDN NNTP Server 1.7 "Bedlam"
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Re[7]: Перегрузить <<
От: jazzer Россия Skype: enerjazzer
Дата: 08.12.03 12:15
Оценка:
Здравствуйте, Павел Кузнецов, Вы писали:

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


ПК>>> Например, следующая программа: <...>

ПК>>> должна печатать:
ПК>>>
 ПК>>> operator << (const char *)
 ПК>>> operator << (int)
 ПК>>> operator << (const char *)
 ПК>>>

ПК>>> безо всяких фокусов.

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


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

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

для нешаблонной функции надо ведь еще преобразование lvalue to rvalue, а для шаблонной — только навесить квалификатор
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[8]: Перегрузить <<
От: Павел Кузнецов  
Дата: 08.12.03 12:39
Оценка:
Здравствуйте, Lorenzo_LAMAS, Вы писали:

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

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

Array-to-pointer имеет ранг Exact Match, поэтому с точки зрения перегрузки эти две функции равны. Например:
void f(const char*);
void f(const char(&)[6]);

int main()
{
  f("число");
}

"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("число");
    ^


В случае же когда одна из этих функций является специализацией шаблона, вторая "выигрывает", т.к.,
грубо говоря, при прочих равных, "обычные" функции (не шаблоны) имеют преимущество перед шаблонами.
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Re[8]: Перегрузить <<
От: Павел Кузнецов  
Дата: 08.12.03 12:43
Оценка:
Здравствуйте, jazzer, Вы писали:

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


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

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

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

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

Это все преобразования ранга Exact Match; здесь есть что-то еще. Также см. http://rsdn.ru/forum/?mid=471103
Автор: Павел Кузнецов
Дата: 08.12.03
Posted via RSDN NNTP Server 1.7 "Bedlam"
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Re[7]: Перегрузить <<
От: Шахтер Интернет  
Дата: 09.12.03 02:51
Оценка:
Здравствуйте, Павел Кузнецов, Вы писали:

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


ПК>>>>> А зачем обе версии: и operator << (char *x), и operator << (const char *x)?


ПК>>> Например, следующая программа: <...> должна печатать:

ПК>>>
 ПК>>> operator << (const char *)
 ПК>>> operator << (int)
 ПК>>> operator << (const char *)
 ПК>>>

ПК>>> безо всяких фокусов.

Ш>> Насчет должна не знаю, мне влом заниматься очередным исследованием стандарта.


ПК>Похоже, не так уж и должна. Похоже мы с 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,
... << RSDN@Home 1.1.0 stable >>
В XXI век с CCore.
Копай Нео, копай -- летать научишься. © Matrix. Парадоксы
Re[9]: Великий и могучий
От: Lorenzo_LAMAS  
Дата: 09.12.03 08:49
Оценка:
ПК>>> не так, и шаблон является лучшим кандидатом — надо будет копнуть поглубже, как только будет время.


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.
Re[10]: Великий и могучий
От: Lorenzo_LAMAS  
Дата: 09.12.03 08:55
Оценка:
Вообще беда — оба вижуала (6.0/7.0) выбрали вторую функцию, а icc первую.
Of course, the code must be complete enough to compile and link.
Re[10]: Великий и могучий
От: achp  
Дата: 09.12.03 09:02
Оценка:
Здравствуйте, 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 с добавлением квалификации. Почему воторое лучше первого?


Это очень скверно. Позволяет ненароком снять константность.
Да здравствует ИМХО!
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[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[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[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. Парадоксы
Re[11]: Перегрузить <<
От: Шахтер Интернет  
Дата: 30.05.04 05:28
Оценка:
Здравствуйте, Павел Кузнецов, Вы писали:

Че-то у меня крыша едет.
Пример.

/* main.cpp */ 

#include <iostream>

using namespace std;

/* main() */ 

template <class T>
void test(const T &) { cout << "1\n" ; }

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

int main()
 {
  test("x");
  
  char *c=0;
  
  test(c);
 
  return 0;
 }


VC++ 7.1 /Za печатает 2 1
Intel C++ 8.0 печатает 1 1

Кто больше?
... << RSDN@Home 1.1.0 stable >>
В XXI век с CCore.
Копай Нео, копай -- летать научишься. © Matrix. Парадоксы
Re[12]: Перегрузить <<
От: Павел Кузнецов  
Дата: 30.05.04 06:09
Оценка:
>
> template <class T>
> void test(const T &) { cout << "1\n" ; }
>
> void test(const char *) { cout << "2\n" ; }
>
> int main()
>  {
>   test("x");
>  char *c=0;
>  test(c);
>  return 0;
>  }
>

>
> VC++ 7.1 /Za печатает 2 1
> Intel C++ 8.0 печатает 1 1

У Интела ошибка, присутствовавшая в старой версии Comeau; она меня раньше
Автор: Павел Кузнецов
Дата: 08.12.03
тоже смутила. В Comeau 4.3.3, использующем более новый EDG-front end, результат совпадает с VC++7.1. Правильным ответом является "2 1".
Posted via RSDN NNTP Server 1.9 alpha
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Re[12]: Перегрузить <<
От: Павел Кузнецов  
Дата: 30.05.04 06:47
Оценка:
> ПК>
> ПК>void test(char const *&);
> ПК>void test(const char (&)[2]);
> ПК>

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

Да, конечно — ссылка в первом случае должна быть тоже константной, т.к. результат преобразования — rvalue.
Posted via RSDN NNTP Server 1.9 alpha
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.