Почему такое компилируется, как вызвать 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;
}
Здравствуйте, Кондор, Вы писали:
К>Почему такое компилируется, как вызвать const версию функции. Или это UB. А может никому просто за ненадобностью и в голову не приходило проверять такое при компиляции...
а почему это не должно компилироваться ?
вызвать const версию например так
В этом случае будет достаточно и static_cast'a. Зачем использовать const_cast кроме как для снятия константности с пути доступа? Это ведь его основное предназначение.
Здравствуйте, Юрий Жмеренецкий, Вы писали:
ЮЖ>В этом случае будет достаточно и static_cast'a. Зачем использовать const_cast кроме как для снятия константности с пути доступа? Это ведь его основное предназначение.
просто, ясно, читабельно, и не туда случайно не приведёшь...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
> В этом случае будет достаточно и static_cast'a. Зачем использовать const_cast кроме как для снятия константности с пути доступа? Это ведь его основное предназначение.
Хм, по-моему на эти вещи надо смотреть иначе — в этом случае будет достаточно и const_cast'a. У статик каста кунфу таки сильнее. Ну и основное пердназначение у него все же не только снимать константность, но и навешивать.
Posted via RSDN NNTP Server 2.1 beta
Одним из 33 полных кавалеров ордена "За заслуги перед Отечеством" является Геннадий Хазанов.
Здравствуйте, Alexander G, Вы писали:
AG>Такая перегрузка применяется часто. У стандартных vector и deque такой operator []
Кстати, из-за этого возникают проблемы со строками. Неконстантный [] делает ей "touch", что
— форсирует Copy On Write, если эта техника используется
— инвалидирует предшествующий c_str() (если это std::string)
— инвалидирует указатели/ссылки на элементы (если используется COW и есть способы получить прямые указатели/ссылки)
А в какой-то версии Dinkum STL — так вообще был баг, итераторы являлись прямыми указателями, при том, что использовался COW.
На RSDN об этом писали.
Здравствуйте, Erop, Вы писали:
E>Здравствуйте, Юрий Жмеренецкий, Вы писали:
ЮЖ>>В этом случае будет достаточно и static_cast'a. Зачем использовать const_cast кроме как для снятия константности с пути доступа? Это ведь его основное предназначение.
E>IMHO, намного добрее такая штука:
E>просто, ясно, читабельно, и не туда случайно не приведёшь...
+1, static_cast только для примера был. Мне вообще так читабельней:
// from boosttemplate <typename T>
inline T implicit_cast(typename identity<T>::type x) {
return x;
}
Многословней, это да...
identity для запрета вывода типа, для того чтобы его всегда надо было указывать.
Ближе к '*_cast' семейству и точнее выражает намерение. Да и тип (при использовании) сразу перед глазами:
implicit_cast<const type&>(*iter).function();
Понятно что иногда явное указание типа только вредит, но иногда и помогает (ака аннотаци типов для ФЯ, но там эффект более глобальный, не только читабельность).
Здравствуйте, Кодт, Вы писали:
К>Кстати, из-за этого возникают проблемы со строками. Неконстантный [] делает ей "touch", что К>- форсирует Copy On Write, если эта техника используется
К>А в какой-то версии Dinkum STL — так вообще был баг, итераторы являлись прямыми указателями, при том, что использовался COW.
Кстати про COW есть мнение что, т.к. счёт ссылок д.б. потокобезопасным, на него достаточно большой оверхед. При этом копия без изменений вряд ли часто нужна. Она может оказаться нужна если используется приём неизменяемых параметров по значению вместо константой ссылки и в случае сложного кода, при котором компилятор не осилит сделать RVO/NRVO.
Т.о. COW — оптимизация для некачественного кода. Не профилировал, но может так и есть
Здравствуйте, Alexander G, Вы писали:
AG>Т.о. COW — оптимизация для некачественного кода. Не профилировал, но может так и есть
Есть смешанные стратегии. Напрмиер, можно кроме счётчика хранить и ID нити, которая осуществляет копирование...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, Alexander G, Вы писали:
AG>Кстати про COW есть мнение что, т.к. счёт ссылок д.б. потокобезопасным, на него достаточно большой оверхед.
Атомарный автоинкремент — не так уж дорого. По сравнению с неатомарным копированием строки. Где-то выиграет копирование, где-то атомарный инкремент.
AG> При этом копия без изменений вряд ли часто нужна. Она может оказаться нужна если используется приём неизменяемых параметров по значению вместо константой ссылки и в случае сложного кода, при котором компилятор не осилит сделать RVO/NRVO. AG>Т.о. COW — оптимизация для некачественного кода. Не профилировал, но может так и есть
Навскидку, если передавать строку по значению в boost::bind, а тем более — в boost::function, то замучаешься — или глубокое копирование, или пляски с бубном вокруг продления жизни ссылаемого объекта.
Ещё COW уравнивает copy- и move-конструирование.
Так что штука в общем полезная. Хотя и расслабляет там, где, возможно, стоило напрячься.
Например, если приходится передавать по значению большой текст — то стоит задуматься: а точно нужно передавать его по значению?
Сегодня используем COW, завтра захотим межпроцессное взаимодействие (RPC, DCOM, etc...) и резко просядем на маршаллинге.
А небольшой текст — фиг с ним, быстрые аллокаторы нас спасут.
Здравствуйте, Кодт, Вы писали:
К>Здравствуйте, 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()'.
Здравствуйте, Sergey, Вы писали:
... >> В этом случае будет достаточно и static_cast'a. Зачем использовать const_cast кроме как для снятия константности с пути доступа? Это ведь его основное предназначение.
S>Хм, по-моему на эти вещи надо смотреть иначе — в этом случае будет достаточно и const_cast'a. У статик каста кунфу таки сильнее. Ну и основное пердназначение у него все же не только снимать константность, но и навешивать.
Имхо, основное предназначение — это то что нельзя (или практически нельзя) сделать с помощью других средств.
" Юрий Жмеренецкий " <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 полных кавалеров ордена "За заслуги перед Отечеством" является Геннадий Хазанов.
Здравствуйте, Юрий Жмеренецкий, Вы писали:
ЮЖ>Это нормальное поведение, в том смысле что в стандарте есть(21.3/5) список операций которые инвалидируют "references, pointers, and iterators referring to the elements of a basic_string sequence". В том числе к этим операциям относится неконстантый 'operator []', а также неконстантная версия функции 'end()'.
Здравствуйте, Sergey, Вы писали:
>> Имхо, основное предназначение — это то что нельзя (или практически нельзя) сделать с помощью других средств.
S>Ну тогда ни у одного из кастов (кроме динамик) основного предназначения нет, потому что все их преобразования на раз делаются си-стайл-кастом.
Ну мы все-таки в С++ форуме... =)
S> А пользоваться, ПМСМ, целесообразнее тем из них, который труднее поломать при дальнейшем сопровождении кода (опять же, кроме динамика). Конст-каст кроме снятия/навешивания cv-квалификаторов (если кто забыл — volatile тоже на его совести) ничего не умеет, потому им и надо здесь пользоваться. В то время как статик-кастом можно ненароком (года через 2, в результате рефакторинга совсем другого кода) случайно скастить предка к потомку, которым он не является.
Про 'поломать' изначально речи не было. Это уже относится к категории 'необходимо', а не 'достаточно'. Кроме того, также крайне желательно выдержать некую читабельность. Здесь уже речь идет о coding style, поэтому и спорить об этом можно бесконечно долго.
Но, например, мне для этого хватает implicit_cast (см. соседний ответ), он обеспечивает озвученную 'неломаемость' и достаточно выразителен, и что более значимо для меня: использование const_cast я воспринимаю (в моих и текущих рамках coding style) именно как снятие константности, т.к эта операция может быть намного опаснее чем навешивание константности.
Здравствуйте, Кодт, Вы писали:
К>Здравствуйте, Юрий Жмеренецкий, Вы писали:
ЮЖ>>Это нормальное поведение, в том смысле что в стандарте есть(21.3/5) список операций которые инвалидируют "references, pointers, and iterators referring to the elements of a basic_string sequence". В том числе к этим операциям относится неконстантый 'operator []', а также неконстантная версия функции 'end()'.
К>
К>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()'. Т.е. на текущий момент — формально его вызов может привести к инвалидации.