Тайный смысл? (void*)this==(void*)&that
От: WolfHound  
Дата: 15.01.04 15:25
Оценка:
Сейчас читаю книжку Вандевурда и Джосатиса про шаблоны и там в операторах присваивания для проверки на присваивание к самому себе исползована такая конструкция
some& operator=(const some& that)
{
    if((void*)this==(void*)&that)
        return *this;
    ...
}

Почему не просто
some& operator=(const some& that)
{
    if(this==&that)
        return *this;
    ...
}

Зачем надо приводить к void*?
... << RSDN@Home 1.1 beta 2 >>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re: Тайный смысл? (void*)this==(void*)&that
От: Bachin Украина  
Дата: 15.01.04 15:37
Оценка: -1
Здравствуйте, WolfHound, Вы писали:

WH>Сейчас читаю книжку Вандевурда и Джосатиса про шаблоны и там в операторах присваивания для проверки на присваивание к самому себе исползована такая конструкция

WH>
WH>some& operator=(const some& that)
WH>{
WH>    if((void*)this==(void*)&that)
WH>        return *this;
WH>    ...
WH>}
WH>

WH>Почему не просто
WH>
WH>some& operator=(const some& that)
WH>{
WH>    if(this==&that)
WH>        return *this;
WH>    ...
WH>}
WH>

WH>Зачем надо приводить к void*?

вероятно потому что интересует сравнивание адресов, а не значчений...
надо бы контекст глянуть...
Best regards,
Oleg A. Bachin
Re: Тайный смысл? (void*)this==(void*)&that
От: BOPOH_N Россия  
Дата: 15.01.04 15:40
Оценка:
Возможно чтобы избежать перегруженных операторов...
В искустве летать есть один маленький секрет. Секрет этот в том,чтобы бросить себя изо всех сил на землю — и не попасть. Выберете погожий денек и попробуйте сами.
Re[2]: Тайный смысл? (void*)this==(void*)&that
От: WolfHound  
Дата: 15.01.04 15:57
Оценка:
Здравствуйте, Bachin, Вы писали:

B>вероятно потому что интересует сравнивание адресов, а не значчений...

B>надо бы контекст глянуть...
А во втором примере что сравнивается? this это указатель that ссылка &that указатель.

ЗЫ Не оверквоть.
... << RSDN@Home 1.1 beta 2 >>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[2]: Тайный смысл? (void*)this==(void*)&that
От: WolfHound  
Дата: 15.01.04 15:57
Оценка:
Здравствуйте, BOPOH_N, Вы писали:

BOP>Возможно чтобы избежать перегруженных операторов...

BOP>
Не думаю. Если мне не изменяет скалероз то указатели это встроеные типа, а для них перегрузка зепрещена.
struct some{};
bool operator==(const some*, const some*)
{
    return false;
}
int main()
{
    return 0;
}

VC++7.1
 error C2803: 'operator ==' must have at least one formal parameter of class type

Comeau C/C++ 4.3.3 (Aug 6 2003 15:13:37) for ONLINE_EVALUATION_BETA1
"ComeauTest.c", line 2: error: nonmember operator requires a parameter with class or
          enum type
  bool operator==(const some*, const some*)
       ^
... << RSDN@Home 1.1 beta 2 >>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[3]: Тайный смысл? (void*)this==(void*)&that
От: Аноним  
Дата: 15.01.04 16:06
Оценка:
Здравствуйте, WolfHound, Вы писали:

WH>Здравствуйте, BOPOH_N, Вы писали:


BOP>>Возможно чтобы избежать перегруженных операторов...

BOP>>
WH>Не думаю. Если мне не изменяет скалероз то указатели это встроеные типа, а для них перегрузка зепрещена.

Но для some же не запрещена...
Re[4]: Тайный смысл? (void*)this==(void*)&that
От: Vladimir Khatzkevich Россия  
Дата: 15.01.04 16:24
Оценка:
Здравствуйте, Аноним, Вы писали:

WH>>Не думаю. Если мне не изменяет скалероз то указатели это встроеные типа, а для них перегрузка зепрещена.


А>Но для some же не запрещена...

Но там же не:
    if(*this==that)
    {}
!!!
Любая сложная технология неотличима от волшебства. (Артур Кларк)
Re: Тайный смысл? (void*)this==(void*)&that
От: Андрей Галюзин Украина  
Дата: 15.01.04 16:24
Оценка:
W> Сейчас читаю книжку Вандевурда и Джосатиса про шаблоны и там в операторах присваивания для
W> проверки на присваивание к самому себе исползована такая конструкция

W> Зачем надо приводить к void*?


Ни к чему это.
И что-то я там такого не припомню. На какой странице?

--
aga
Posted via RSDN NNTP Server 1.7 "Bedlam"
Re: не совсем по теме
От: davenger  
Дата: 15.01.04 16:26
Оценка:
Здравствуйте, WolfHound, Вы писали:

WH>Сейчас читаю книжку Вандевурда и Джосатиса про шаблоны и там в операторах присваивания для проверки на присваивание к самому себе исползована такая конструкция


В той же книжке написано, что шаблонный оператор = не перекрывает оператор копирования (т.е. const A& A::operator = (const A&) ):

Note that a template assignment operator doesn't replace the default assignment operator. For assignments of stacks of the same type, the default assignment operator is still called.



, и рядом с этим написан код типа:


template <typename T> 
 template <typename T2> 
Stack<T>& Stack<T>::operator= (Stack<T2> const& op2) 
{ 
    if ((void*)this == (void*)&op2) {    // assignment to itself? 
        return *this; 
    } 

    Stack<T2> tmp(op2);             // create a copy of the assigned stack 

    elems.clear();                  // remove existing elements 
    while (!tmp.empty()) {          // copy all elements 
        elems.push_front(tmp.top()); 
        tmp.pop(); 
    } 
    return *this; 
}


не понятен смысл проверки (void*)this == (void*)&op2
Re[2]: Тайный смысл? (void*)this==(void*)&that
От: davenger  
Дата: 15.01.04 16:29
Оценка:
Здравствуйте, Андрей Галюзин, Вы писали:

W>> Сейчас читаю книжку Вандевурда и Джосатиса про шаблоны и там в операторах присваивания для

W>> проверки на присваивание к самому себе исползована такая конструкция

W>> Зачем надо приводить к void*?


АГ>Ни к чему это.

АГ>И что-то я там такого не припомню. На какой странице?

Может это как раз про тот случай, когда оператор "=" шаблонный, чтоб не сравнивать указатели разного типа, но тогда не понятно, какой в этом смысл, как я уже ниже спросил.

АГ>--

АГ>aga
Re[2]: Тайный смысл? (void*)this==(void*)&that
От: Андрей Тарасевич Беларусь  
Дата: 15.01.04 16:44
Оценка: +1
Здравствуйте, BOPOH_N, Вы писали:

BOP>Возможно чтобы избежать перегруженных операторов...

BOP>

У указателей, как и у любых других встроенных типов, не может быть перегруженных операторов.
Best regards,
Андрей Тарасевич
Re[2]: не совсем по теме
От: Андрей Галюзин Украина  
Дата: 15.01.04 16:47
Оценка: 2 (1)
d> В той же книжке написано, что шаблонный оператор = не перекрывает оператор копирования (т.е.
d> const A& A::operator = (const A&) ):

Так и есть.

d> , и рядом с этим написан код типа:


d>
d> template <typename T>
d>  template <typename T2>
d> Stack<T>& Stack<T>::operator= (Stack<T2> const& op2)
d> {
d>     if ((void*)this == (void*)&op2) {    // assignment to itself?
d>         return *this;
d>     }
d> ...
d>     return *this;
d> }
d>


d> не понятен смысл проверки (void*)this == (void*)&op2


Но ведь можно попросить вызвать именно этот оператор

Stack<int> a1;
Stack<int> a2;
a1.operator=<int>(a2);


Вероятно, для такого случая и стоит проверка.

--
aga
Posted via RSDN NNTP Server 1.7 "Bedlam"
Re[2]: не совсем по теме
От: Vladimir Levchuk Украина  
Дата: 15.01.04 19:30
Оценка:
Здравствуйте, davenger, Вы писали:

D>Здравствуйте, WolfHound, Вы писали:


WH>>Сейчас читаю книжку Вандевурда и Джосатиса про шаблоны и там в операторах присваивания для проверки на присваивание к самому себе исползована такая конструкция

....
[skipped]

D>, и рядом с этим написан код типа:



D>
D>template <typename T> 
D> template <typename T2> 
D>Stack<T>& Stack<T>::operator= (Stack<T2> const& op2) 
D>{ 
D>    if ((void*)this == (void*)&op2) {    // assignment to itself? 
D>        return *this; 
D>    } 

D>    Stack<T2> tmp(op2);             // create a copy of the assigned stack 

D>    elems.clear();                  // remove existing elements 
D>    while (!tmp.empty()) {          // copy all elements 
D>        elems.push_front(tmp.top()); 
D>        tmp.pop(); 
D>    } 
D>    return *this; 
D>} 
D>


D>не понятен смысл проверки (void*)this == (void*)&op2


Кажется, дело в том, что здесь this и op2 — разных типов T* и T2*.
Если сравнивать this == op2, то фактически выполниться this == (T*) op2.
А привести ситуацию, когда ((void*) op2 != (void*) (T*) op2) совсем несложно:

#include <stdio.h>
struct A { int a; };
struct B { int b; };

struct C : public A, public B
{
    void test(B * p)
    {
        printf ("this %s p\n", 
            (this == p) ? "==" : "!=" );
        printf("(void*)this %s (void*)p", 
            ((void*)this == (void*)p) ? "==" : "!=");
    };
};

void main()
{
    C c;
    c.test(&c);
};


ЗЫ: хотя сложно представить ситуацию когда такое сравнение пригодится
--------------------------
WBR,
Leva mailto:leva@nm.ru,
ICQ: 106191183
Re: Тайный смысл? (void*)this==(void*)&that
От: Thanatos Украина  
Дата: 15.01.04 19:49
Оценка: 14 (2)
Здравствуйте, WolfHound, Вы писали:

WH>Почему не просто

WH>
WH>some& operator=(const some& that)
WH>{
WH>    if(this==&that)
WH>        return *this;
WH>    ...
WH>}
WH>

WH>Зачем надо приводить к void*?

Имхо — потому что может быть перегружен &.
И некоторые компиляторы не прокушают то, что получится.
Лучший дар, который мы получили от природы и который лишает нас всякого права жаловаться – это возможность сбежать. /М.Монтень/
Re[2]: Тайный смысл? (void*)this==(void*)&that
От: Шахтер Интернет  
Дата: 15.01.04 20:12
Оценка: 4 (1)
Здравствуйте, Thanatos, Вы писали:

T>Здравствуйте, WolfHound, Вы писали:


WH>>Почему не просто

WH>>
WH>>some& operator=(const some& that)
WH>>{
WH>>    if(this==&that)
WH>>        return *this;
WH>>    ...
WH>>}
WH>>

WH>>Зачем надо приводить к void*?

T>Имхо — потому что может быть перегружен &.

T>И некоторые компиляторы не прокушают то, что получится.

Первое выражение не решает этой проблеммы (с приведение типа к (void *)). Поскольку будет оперировать с результатом, возвращённым перегруженным оператором.
В бусте была примочка для этих случаев -- грязный хак, однако.

namespace boost {

// Do not make addressof() inline. Breaks MSVC 7. (Peter Dimov)

// VC7 strips const from nested classes unless we add indirection here
# if BOOST_WORKAROUND(BOOST_MSVC, == 1300)
template <typename T> typename add_pointer<T>::type
# else
template <typename T> T*
# endif
addressof(T& v)
{
  return reinterpret_cast<T*>(
       &const_cast<char&>(reinterpret_cast<const volatile char &>(v)));
}

}
... << RSDN@Home 1.1.0 stable >>
В XXI век с CCore.
Копай Нео, копай -- летать научишься. © Matrix. Парадоксы
Re[2]: не совсем по теме
От: alexkro  
Дата: 15.01.04 22:06
Оценка:
Здравствуйте, davenger, Вы писали:

D>Здравствуйте, WolfHound, Вы писали:


D>В той же книжке написано, что шаблонный оператор = не перекрывает оператор копирования (т.е. const A& A::operator = (const A&) ):


Если не перекрывает, то как может Stack быть присвоен самому себе через шаблонный оператор =?

D>

D>Note that a template assignment operator doesn't replace the default assignment operator. For assignments of stacks of the same type, the default assignment operator is still called.


Для присвоения самому себе type will be the same.

D>, и рядом с этим написан код типа:



D>
D>template <typename T> 
D> template <typename T2> 
D>Stack<T>& Stack<T>::operator= (Stack<T2> const& op2) 
D>{ 
D>    if ((void*)this == (void*)&op2) {    // assignment to itself? 
D>        return *this; 
D>    } 

D>    Stack<T2> tmp(op2);             // create a copy of the assigned stack 

D>    elems.clear();                  // remove existing elements 
D>    while (!tmp.empty()) {          // copy all elements 
D>        elems.push_front(tmp.top()); 
D>        tmp.pop(); 
D>    } 
D>    return *this; 
D>} 
D>


Вообще, код:
1) not exception safe,
2) проверка на присвоение самому себе не нужна, если правильно написать operator=. По моему, Саттер или Майерс на эту тему писали.

My 2 cents:
template <typename T> 
 template <typename T2> 
Stack<T>& Stack<T>::operator= (Stack<T2> const& op2) 
{ 
    Stack<T> newthis;
    Stack<T2> tmp(op2);             // create a copy of the assigned stack 

    while (!tmp.empty()) {          // copy all elements 
        newthis.push_front(tmp.top()); 
        tmp.pop(); 
    } 

    newthis.swap( *this );
    return *this; 
}
Re[2]: не совсем по теме
От: leper Россия  
Дата: 16.01.04 08:18
Оценка:
Здравствуйте, davenger, Вы писали:

D>Здравствуйте, WolfHound, Вы писали:


D>
D>template <typename T> 
D> template <typename T2> 
D>Stack<T>& Stack<T>::operator= (Stack<T2> const& op2) 
D>{ 
D>    if ((void*)this == (void*)&op2) {    // assignment to itself? 
D>        return *this; 
D>    } 

D>    Stack<T2> tmp(op2);             // create a copy of the assigned stack 

D>    elems.clear();                  // remove existing elements 
D>    while (!tmp.empty()) {          // copy all elements 
D>        elems.push_front(tmp.top()); 
D>        tmp.pop(); 
D>    } 
D>    return *this; 
D>} 
D>


D>не понятен смысл проверки (void*)this == (void*)&op2


Это опечатка, о этом говориться здесь:

Page 47 (stack5assign.hpp),
Page 49 (stack6assign.hpp),
Page 54 (stack8.hpp):
In the templified assignment operator of Stack the test of assignment to itself is useless because the template member assignment operator is never used for assignment between objects of the same type, and if the address of rhs == this, then the object must reasonably be of the same type.

... << RSDN@Home 1.1.0 stable >>
Think for yourself. Question authory.
Re[3]: не совсем по теме
От: Lorenzo_LAMAS  
Дата: 16.01.04 08:33
Оценка:
Да, но, с другой стороны, что мне мешает написать
int main()
{
   A<int>a;
   a.operator=<>(a);

   return 0;
}


Тут уже проверка явно не помешает, а если типы операндов разные, то понятно преобразование к void *
Of course, the code must be complete enough to compile and link.
Re[4]: не совсем по теме
От: leper Россия  
Дата: 16.01.04 08:59
Оценка:
Здравствуйте, Lorenzo_LAMAS, Вы писали:

L_L>Да, но, с другой стороны, что мне мешает написать

L_L>
L_L>int main()
L_L>{
   A<int>>a;
L_L>   a.operator=<>(a);

L_L>   return 0;
L_L>}
L_L>


L_L>Тут уже проверка явно не помешает, а если типы операндов разные, то понятно преобразование к void *


Полностью согласен, просто привел ссылку по которой лежит список того, что авторы сочли опечатками. К сожалению, при переводе их не учли . Так что, заглянуть туда иногда полезно.
... << RSDN@Home 1.1.0 stable >>
Think for yourself. Question authory.
Re[5]: не совсем по теме
От: Lorenzo_LAMAS  
Дата: 16.01.04 09:02
Оценка:
L>Полностью согласен, просто привел ссылку по которой лежит список того, что авторы сочли опечатками. К сожалению, при переводе их не учли . Так что, заглянуть туда иногда полезно.

Да, у меня тоже есть список опечаток (книга у меня не переводная). У Бьярна тоже есть errata но уж больно много изданий и, соответственно, errata
Of course, the code must be complete enough to compile and link.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.