Re[3]: to_const
От: Erop Россия  
Дата: 13.01.09 08:50
Оценка: 3 (2) +1
Здравствуйте, Юрий Жмеренецкий, Вы писали:

ЮЖ>В этом случае будет достаточно и static_cast'a. Зачем использовать const_cast кроме как для снятия константности с пути доступа? Это ведь его основное предназначение.


IMHO, намного добрее такая штука:
template<typename T> const T& to_const( T& a ) { return a; }
template<typename T> const T& to_const( const T& a ) { return a; }
template<typename T> const T* to_const( T* a ) { return a; }
template<typename T> const T* to_const( const T* a ) { return a; }
просто, ясно, читабельно, и не туда случайно не приведёшь...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[6]: Перегрузка функций класса и const
От: Юрий Жмеренецкий ICQ 380412032
Дата: 13.01.09 14:25
Оценка: -1 :)
Здравствуйте, Sergey, Вы писали:

>> Имхо, основное предназначение — это то что нельзя (или практически нельзя) сделать с помощью других средств.


S>Ну тогда ни у одного из кастов (кроме динамик) основного предназначения нет, потому что все их преобразования на раз делаются си-стайл-кастом.

Ну мы все-таки в С++ форуме... =)

S> А пользоваться, ПМСМ, целесообразнее тем из них, который труднее поломать при дальнейшем сопровождении кода (опять же, кроме динамика). Конст-каст кроме снятия/навешивания cv-квалификаторов (если кто забыл — volatile тоже на его совести) ничего не умеет, потому им и надо здесь пользоваться. В то время как статик-кастом можно ненароком (года через 2, в результате рефакторинга совсем другого кода) случайно скастить предка к потомку, которым он не является.


Про 'поломать' изначально речи не было. Это уже относится к категории 'необходимо', а не 'достаточно'. Кроме того, также крайне желательно выдержать некую читабельность. Здесь уже речь идет о coding style, поэтому и спорить об этом можно бесконечно долго.

Но, например, мне для этого хватает implicit_cast (см. соседний ответ), он обеспечивает озвученную 'неломаемость' и достаточно выразителен, и что более значимо для меня: использование const_cast я воспринимаю (в моих и текущих рамках coding style) именно как снятие константности, т.к эта операция может быть намного опаснее чем навешивание константности.
Re: Перегрузка функций класса и const
От: _Dreamer Россия  
Дата: 13.01.09 06:46
Оценка: 1 (1)
Здравствуйте, Кондор, Вы писали:

К>Почему такое компилируется, как вызвать const версию функции. Или это UB. А может никому просто за ненадобностью и в голову не приходило проверять такое при компиляции...


а почему это не должно компилироваться ?
вызвать const версию например так

A a_;
a_.f(); // non-const
const_cast<const A&>(a_).f(); // const

const A& ac_ = a_;
ac_.f(); // const
Re: Перегрузка функций класса и const
От: Alexander G Украина  
Дата: 13.01.09 07:00
Оценка: 1 (1)
Здравствуйте, Кондор, Вы писали:

К> А может никому просто за ненадобностью и в голову не приходило проверять такое при компиляции...



Такая перегрузка применяется часто. У стандартных vector и deque такой operator []
Русский военный корабль идёт ко дну!
Перегрузка функций класса и const
От: Кондор Россия  
Дата: 13.01.09 06:28
Оценка: :)
Почему такое компилируется, как вызвать const версию функции. Или это UB. А может никому просто за ненадобностью и в голову не приходило проверять такое при компиляции...
struct A
{
    void f()
    {
        cout<<"A::f()"<<endl;
    }

    void f() const
    {
        cout<<"A::f() const"<<endl;
    }
};
int _tmain(int argc, _TCHAR* argv[])
{    
    A a;
    a.f();
    return 0;
}
ДДТ!
Re[3]: Перегрузка функций класса и const
От: Sergey Россия  
Дата: 13.01.09 09:31
Оценка: -1
" Юрий Жмеренецкий " <47281@users.rsdn.ru> wrote in message news:3245983@news.rsdn.ru...

> _D>вызвать const версию например так

>
> _D>
> _D>A a_;
> _D>a_.f(); // non-const
> _D>const_cast<const A&>(a_).f(); // const
> 
> _D>

> В этом случае будет достаточно и static_cast'a. Зачем использовать const_cast кроме как для снятия константности с пути доступа? Это ведь его основное предназначение.

Хм, по-моему на эти вещи надо смотреть иначе — в этом случае будет достаточно и const_cast'a. У статик каста кунфу таки сильнее. Ну и основное пердназначение у него все же не только снимать константность, но и навешивать.
Posted via RSDN NNTP Server 2.1 beta
Одним из 33 полных кавалеров ордена "За заслуги перед Отечеством" является Геннадий Хазанов.
Re[4]: Перегрузка функций класса и const
От: Кодт Россия  
Дата: 13.01.09 12:16
Оценка: +1
Здравствуйте, Alexander G, Вы писали:

AG>Кстати про COW есть мнение что, т.к. счёт ссылок д.б. потокобезопасным, на него достаточно большой оверхед.


Атомарный автоинкремент — не так уж дорого. По сравнению с неатомарным копированием строки. Где-то выиграет копирование, где-то атомарный инкремент.

AG> При этом копия без изменений вряд ли часто нужна. Она может оказаться нужна если используется приём неизменяемых параметров по значению вместо константой ссылки и в случае сложного кода, при котором компилятор не осилит сделать RVO/NRVO.

AG>Т.о. COW — оптимизация для некачественного кода. Не профилировал, но может так и есть

Навскидку, если передавать строку по значению в boost::bind, а тем более — в boost::function, то замучаешься — или глубокое копирование, или пляски с бубном вокруг продления жизни ссылаемого объекта.
Ещё COW уравнивает copy- и move-конструирование.

Так что штука в общем полезная. Хотя и расслабляет там, где, возможно, стоило напрячься.

Например, если приходится передавать по значению большой текст — то стоит задуматься: а точно нужно передавать его по значению?
Сегодня используем COW, завтра захотим межпроцессное взаимодействие (RPC, DCOM, etc...) и резко просядем на маршаллинге.
А небольшой текст — фиг с ним, быстрые аллокаторы нас спасут.
... << RSDN@Home 1.2.0 alpha 4 rev. 1111>>
Перекуём баги на фичи!
Re[3]: Перегрузка функций класса и const
От: Юрий Жмеренецкий ICQ 380412032
Дата: 13.01.09 12:34
Оценка: :)
Здравствуйте, Кодт, Вы писали:

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


AG>>Такая перегрузка применяется часто. У стандартных vector и deque такой operator []


К>Кстати, из-за этого возникают проблемы со строками. Неконстантный [] делает ей "touch", что

К>- форсирует Copy On Write, если эта техника используется
К>- инвалидирует предшествующий c_str() (если это std::string)
К>- инвалидирует указатели/ссылки на элементы (если используется COW и есть способы получить прямые указатели/ссылки)

Это нормальное поведение, в том смысле что в стандарте есть(21.3/5) список операций которые инвалидируют "references, pointers, and iterators referring to the elements of a basic_string sequence". В том числе к этим операциям относится неконстантый 'operator []', а также неконстантная версия функции 'end()'.
Re[5]: Перегрузка функций класса и const
От: Sergey Россия  
Дата: 13.01.09 13:28
Оценка: +1
" Юрий Жмеренецкий " <47281@users.rsdn.ru> wrote in message news:3246586@news.rsdn.ru...

>>> В этом случае будет достаточно и static_cast'a. Зачем использовать const_cast кроме как для снятия константности с пути доступа? Это ведь его основное предназначение.

>
> S>Хм, по-моему на эти вещи надо смотреть иначе — в этом случае будет достаточно и const_cast'a. У статик каста кунфу таки сильнее. Ну и основное пердназначение у него все же не только снимать константность, но и навешивать.

> Имхо, основное предназначение — это то что нельзя (или практически нельзя) сделать с помощью других средств.


Ну тогда ни у одного из кастов (кроме динамик) основного предназначения нет, потому что все их преобразования на раз делаются си-стайл-кастом. А пользоваться, ПМСМ, целесообразнее тем из них, который труднее поломать при дальнейшем сопровождении кода (опять же, кроме динамика). Конст-каст кроме снятия/навешивания cv-квалификаторов (если кто забыл — volatile тоже на его совести) ничего не умеет, потому им и надо здесь пользоваться. В то время как статик-кастом можно ненароком (года через 2, в результате рефакторинга совсем другого кода) случайно скастить предка к потомку, которым он не является.
Posted via RSDN NNTP Server 2.1 beta
Одним из 33 полных кавалеров ордена "За заслуги перед Отечеством" является Геннадий Хазанов.
Re[4]: Перегрузка функций класса и const
От: Кодт Россия  
Дата: 13.01.09 13:38
Оценка: +1
Здравствуйте, Юрий Жмеренецкий, Вы писали:

ЮЖ>Это нормальное поведение, в том смысле что в стандарте есть(21.3/5) список операций которые инвалидируют "references, pointers, and iterators referring to the elements of a basic_string sequence". В том числе к этим операциям относится неконстантый 'operator []', а также неконстантная версия функции 'end()'.


for(iterator i=str.begin(), e=str.end(); i!=e; ++i)
    *i = 'a';

1) str.end() инвалидирует свежевзятый i=str.begin() ?!
2) *i или *i='a' инвалидирует i и e?
... << RSDN@Home 1.2.0 alpha 4 rev. 1111>>
Перекуём баги на фичи!
Re[2]: Перегрузка функций класса и const
От: Юрий Жмеренецкий ICQ 380412032
Дата: 13.01.09 08:44
Оценка:
Здравствуйте, _Dreamer, Вы писали:
...
_D>вызвать const версию например так

_D>
_D>A a_;
_D>a_.f(); // non-const
_D>const_cast<const A&>(a_).f(); // const

_D>

В этом случае будет достаточно и static_cast'a. Зачем использовать const_cast кроме как для снятия константности с пути доступа? Это ведь его основное предназначение.
Re[2]: Перегрузка функций класса и const
От: Кодт Россия  
Дата: 13.01.09 09:50
Оценка:
Здравствуйте, Alexander G, Вы писали:

AG>Такая перегрузка применяется часто. У стандартных vector и deque такой operator []


Кстати, из-за этого возникают проблемы со строками. Неконстантный [] делает ей "touch", что
— форсирует Copy On Write, если эта техника используется
— инвалидирует предшествующий c_str() (если это std::string)
— инвалидирует указатели/ссылки на элементы (если используется COW и есть способы получить прямые указатели/ссылки)

А в какой-то версии Dinkum STL — так вообще был баг, итераторы являлись прямыми указателями, при том, что использовался COW.
На RSDN об этом писали.
... << RSDN@Home 1.2.0 alpha 4 rev. 1111>>
Перекуём баги на фичи!
Re[4]: implicit_cast
От: Юрий Жмеренецкий ICQ 380412032
Дата: 13.01.09 10:01
Оценка:
Здравствуйте, Erop, Вы писали:

E>Здравствуйте, Юрий Жмеренецкий, Вы писали:


ЮЖ>>В этом случае будет достаточно и static_cast'a. Зачем использовать const_cast кроме как для снятия константности с пути доступа? Это ведь его основное предназначение.


E>IMHO, намного добрее такая штука:

template<typename T> const T& to_const( T& a ) { return a; }
E>template<typename T> const T& to_const( const T& a ) { return a; }
E>template<typename T> const T* to_const( T* a ) { return a; }
E>template<typename T> const T* to_const( const T* a ) { return a; }

E>просто, ясно, читабельно, и не туда случайно не приведёшь...

+1, static_cast только для примера был. Мне вообще так читабельней:
 
// from boost
template <typename T> 
inline T implicit_cast(typename identity<T>::type x) {
    return x;
}

Многословней, это да...
identity для запрета вывода типа, для того чтобы его всегда надо было указывать.
Ближе к '*_cast' семейству и точнее выражает намерение. Да и тип (при использовании) сразу перед глазами:
implicit_cast<const type&>(*iter).function();

Понятно что иногда явное указание типа только вредит, но иногда и помогает (ака аннотаци типов для ФЯ, но там эффект более глобальный, не только читабельность).
Re[3]: Перегрузка функций класса и const
От: Alexander G Украина  
Дата: 13.01.09 10:51
Оценка:
Здравствуйте, Кодт, Вы писали:

К>Кстати, из-за этого возникают проблемы со строками. Неконстантный [] делает ей "touch", что

К>- форсирует Copy On Write, если эта техника используется

К>А в какой-то версии Dinkum STL — так вообще был баг, итераторы являлись прямыми указателями, при том, что использовался COW.


Кстати про COW есть мнение что, т.к. счёт ссылок д.б. потокобезопасным, на него достаточно большой оверхед. При этом копия без изменений вряд ли часто нужна. Она может оказаться нужна если используется приём неизменяемых параметров по значению вместо константой ссылки и в случае сложного кода, при котором компилятор не осилит сделать RVO/NRVO.
Т.о. COW — оптимизация для некачественного кода. Не профилировал, но может так и есть
Русский военный корабль идёт ко дну!
Re[4]: Перегрузка функций класса и const
От: Erop Россия  
Дата: 13.01.09 12:14
Оценка:
Здравствуйте, Alexander G, Вы писали:

AG>Т.о. COW — оптимизация для некачественного кода. Не профилировал, но может так и есть

Есть смешанные стратегии. Напрмиер, можно кроме счётчика хранить и ID нити, которая осуществляет копирование...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[4]: Перегрузка функций класса и const
От: Юрий Жмеренецкий ICQ 380412032
Дата: 13.01.09 13:07
Оценка:
Здравствуйте, Sergey, Вы писали:
...
>> В этом случае будет достаточно и static_cast'a. Зачем использовать const_cast кроме как для снятия константности с пути доступа? Это ведь его основное предназначение.

S>Хм, по-моему на эти вещи надо смотреть иначе — в этом случае будет достаточно и const_cast'a. У статик каста кунфу таки сильнее. Ну и основное пердназначение у него все же не только снимать константность, но и навешивать.


Имхо, основное предназначение — это то что нельзя (или практически нельзя) сделать с помощью других средств.
Re[5]: Перегрузка функций класса и const
От: Юрий Жмеренецкий ICQ 380412032
Дата: 13.01.09 14:54
Оценка:
Здравствуйте, Кодт, Вы писали:

К>Здравствуйте, Юрий Жмеренецкий, Вы писали:


ЮЖ>>Это нормальное поведение, в том смысле что в стандарте есть(21.3/5) список операций которые инвалидируют "references, pointers, and iterators referring to the elements of a basic_string sequence". В том числе к этим операциям относится неконстантый 'operator []', а также неконстантная версия функции 'end()'.


К>
К>for(iterator i=str.begin(), e=str.end(); i!=e; ++i)
К>    *i = 'a';
К>

К>1) str.end() инвалидирует свежевзятый i=str.begin() ?!
К>2) *i или *i='a' инвалидирует i и e?

Извеняюсь, переврал. В голове крутился баг с финализацией строки неконстантным end'ом в какой-то из реализаций. В оригинале так:

References, pointers, and iterators referring to the elements of a basic_string sequence may be invalidated
by the following uses of that basic_string object:
...
— Calling data() and c_str() member functions
...
— Subsequent to any of the above uses except the forms of insert() and erase() which return iterators,
the first call to non-const member functions operator[](), at(), begin(), rbegin(),
end(), or rend()
.


А вот с 'operator []' в текущем стандарте оказался косяк: обе версии определены через 'data()'. Т.е. на текущий момент — формально его вызов может привести к инвалидации.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.