Сейчас читаю книжку Вандевурда и Джосатиса про шаблоны и там в операторах присваивания для проверки на присваивание к самому себе исползована такая конструкция
Здравствуйте, WolfHound, Вы писали:
WH>Сейчас читаю книжку Вандевурда и Джосатиса про шаблоны и там в операторах присваивания для проверки на присваивание к самому себе исползована такая конструкция WH>
Возможно чтобы избежать перегруженных операторов...
В искустве летать есть один маленький секрет. Секрет этот в том,чтобы бросить себя изо всех сил на землю — и не попасть. Выберете погожий денек и попробуйте сами.
Здравствуйте, Bachin, Вы писали:
B>вероятно потому что интересует сравнивание адресов, а не значчений... B>надо бы контекст глянуть...
А во втором примере что сравнивается? this это указатель that ссылка &that указатель.
ЗЫ Не оверквоть.
... << RSDN@Home 1.1 beta 2 >>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Здравствуйте, BOPOH_N, Вы писали:
BOP>Возможно чтобы избежать перегруженных операторов... BOP>
Не думаю. Если мне не изменяет скалероз то указатели это встроеные типа, а для них перегрузка зепрещена.
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>Не думаю. Если мне не изменяет скалероз то указатели это встроеные типа, а для них перегрузка зепрещена.
Здравствуйте, Аноним, Вы писали:
WH>>Не думаю. Если мне не изменяет скалероз то указатели это встроеные типа, а для них перегрузка зепрещена.
А>Но для some же не запрещена...
Но там же не:
if(*this==that)
{}
!!!
Любая сложная технология неотличима от волшебства. (Артур Кларк)
W> Сейчас читаю книжку Вандевурда и Джосатиса про шаблоны и там в операторах присваивания для W> проверки на присваивание к самому себе исползована такая конструкция
W> Зачем надо приводить к void*?
Ни к чему это.
И что-то я там такого не припомню. На какой странице?
Здравствуйте, 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
Здравствуйте, Андрей Галюзин, Вы писали:
W>> Сейчас читаю книжку Вандевурда и Джосатиса про шаблоны и там в операторах присваивания для W>> проверки на присваивание к самому себе исползована такая конструкция
W>> Зачем надо приводить к void*?
АГ>Ни к чему это. АГ>И что-то я там такого не припомню. На какой странице?
Может это как раз про тот случай, когда оператор "=" шаблонный, чтоб не сравнивать указатели разного типа, но тогда не понятно, какой в этом смысл, как я уже ниже спросил.
АГ>-- АГ>aga
Здравствуйте, 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>
Кажется, дело в том, что здесь 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);
};
ЗЫ: хотя сложно представить ситуацию когда такое сравнение пригодится
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)));
}
}
Здравствуйте, 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;
}
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.
L_L>Тут уже проверка явно не помешает, а если типы операндов разные, то понятно преобразование к void *
Полностью согласен, просто привел ссылку по которой лежит список того, что авторы сочли опечатками. К сожалению, при переводе их не учли . Так что, заглянуть туда иногда полезно.
L>Полностью согласен, просто привел ссылку по которой лежит список того, что авторы сочли опечатками. К сожалению, при переводе их не учли . Так что, заглянуть туда иногда полезно.
Да, у меня тоже есть список опечаток (книга у меня не переводная). У Бьярна тоже есть errata но уж больно много изданий и, соответственно, errata
Of course, the code must be complete enough to compile and link.