- 1
bool ok = (state == 0) ? false : true;
Нашли или выдавили из себя код, который нельзя назвать нормальным, на который без улыбки не взглянешь? Не торопитесь его удалять или рефакторить, — запостите его на говнокод.ру, посмеёмся вместе!
−43
bool ok = (state == 0) ? false : true;
И это пишет человек, пишущий на плюсах уже много лет...
bormand 05.06.2012 12:53 # +8
glook 05.06.2012 12:56 # −3
Pediastr 05.06.2012 13:17 # −2
glook 05.06.2012 13:26 # −2
TarasB 05.06.2012 16:14 # −3
TheHamstertamer 05.06.2012 16:33 # +2
TarasB 05.06.2012 20:05 # −1
lucidfoxGovno 06.06.2012 01:59 # −8
GravatarGovno 21.07.2021 00:11 # 0
Kirinyale 06.06.2012 18:47 # +4
иначе некоторые компиляторы могут ругаться варнингами типа forcing int value to bool
ForEveR 09.06.2012 14:05 # −2
bormand 09.06.2012 14:12 # 0
bormand 09.06.2012 14:18 # +2
ForEveR 09.06.2012 14:36 # +1
ЗЫ ok = state != 0 не заработает без перегрузки соответствующего оператора.
http://liveworkspace.org/code/47a683ac91ec0b441cbd6ce3b0e2ea35
bormand 09.06.2012 14:38 # +1
Так что будем считать, что != перегружено.
ForEveR 09.06.2012 14:39 # 0
interested 24.06.2012 20:19 # 0
bool ok = static_cast<bool>(state);
:)
bormand 24.06.2012 20:38 # 0
TarasB 24.06.2012 20:44 # +2
interested 24.06.2012 20:49 # 0
Код читается по-разному:
i) bool ok = state == 0; => положи в ok флаг соответствия state состоянию int 0
ii) bool ok = static_cast<bool>(state); => положи в ok битовое соответствие state.
TarasB 24.06.2012 20:51 # +3
interested 24.06.2012 20:52 # −1
Скажешь какую-нибудь ерунду не по делу :)
TarasB 24.06.2012 20:54 # 0
bormand 24.06.2012 20:58 # 0
http://ideone.com/SCWMZ
TarasB 24.06.2012 21:02 # 0
rat4 24.06.2012 21:14 # 0
interested 24.06.2012 21:01 # 0
bormand 24.06.2012 20:53 # 0
Это не с++ way а какое-то байтоебство.
interested 24.06.2012 20:58 # 0
bormand 24.06.2012 21:02 # 0
Так вот к чему я клоню - зачем применять каст там где он сроду не нужен, и можно написать простое, универсальное и понятное всем state == 0?
interested 24.06.2012 21:06 # 0
private:
int INTSTATE;
SomeEnumState ENUMSTATE;
public:
bool() {
return INTSTATE == 42 || ENUMSTATE == ESUCCESS;
}
};
bormand 24.06.2012 21:09 # 0
interested 24.06.2012 21:13 # 0
bormand 24.06.2012 21:21 # 0
bool b = state;
Поскольку bool() не explicit - все будет работать. Если же у нас с++11 и оператор explicit - то да, нужен каст. Но в таких случаях, имхо, лучше isSuccess(). Короче чем каст, и лучше показывает намерения.
rat4 24.06.2012 20:41 # +2
bormand 24.06.2012 20:51 # 0
rat4 24.06.2012 21:19 # +2
Конечно, http://ideone.com/HLLIH
bormand 24.06.2012 21:26 # +1
А еще можно было !(state ^ answer)
defecate-plusplus 24.06.2012 21:01 # +6
bool ok = state;
state - конечно же, объект, в котором есть operator bool () (на крайний говнослучай, не будем показывать пальцем - operator void *())
interested 24.06.2012 21:08 # −2
С++ way: double b = static_cast<double>(3)/static_cast<double>(2);
defecate-plusplus 24.06.2012 21:10 # 0
interested 24.06.2012 21:12 # 0
У вас написано: положи в ok state o.O причём они разных типов... Fail!
defecate-plusplus 24.06.2012 21:15 # +1
да, мсье ведь в курсе, что в с++ все три приведения типов эквивалентны:
interested 24.06.2012 21:17 # 0
Вот если bool ok = static_cast<bool>(state); То да, как раз так. Специально и придумали эти штуки, чтобы читать можно было, а не домысливать из "вселенского разума". Это ж один из немногих профитов C++.
defecate-plusplus 24.06.2012 21:22 # 0
bool x = z;
z приводится к типу bool
да, именно с помощью static_cast приводится к bool неявно
да, c-cast, записанный как (bool), для целочисленных типов будет приводиться компилятором как static_cast
interested 24.06.2012 21:29 # 0
defecate-plusplus 24.06.2012 21:32 # +2
опять искалеченные паскалем судьбы в православных разделах на гк??
interested 24.06.2012 21:36 # −1
defecate-plusplus 24.06.2012 21:40 # 0
4.12/1
[conv.bool] 4.12 Boolean conversions
An rvalue of arithmetic, enumeration, pointer, or pointer to member type can be converted to an rvalue of type bool. A zero value, null pointer value, or null member pointer value is converted to false; any other value is converted to true.
очень запутанные вещи написаны в стандарте, очень
interested 24.06.2012 21:41 # 0
Когда в коде становится много всяких подобных abandon слов, приходится дочитывать то, что не написано. Это хорошо в художественной литературе, а не в коде.
Кто экономит на чистоте: тот или вор, или свинья. ;)
interested 24.06.2012 21:40 # −1
defecate-plusplus 24.06.2012 21:41 # +1
bormand 24.06.2012 21:39 # 0
interested 24.06.2012 21:48 # 0
Я хочу создать один объект из другого и я точно знаю что, я уверен, что это возможно разрешить на стадии компиляции... И прочее бла, бла, бла.
Когда вы хотите что-то спросить у человека, вы подходите и заявляете: "Скажи-ка дядя, ты не видал здесь такого... с пупочкой?" или "Милостивый государь, не соблаговолите ли вы <...>"
Вот и разница между неявным и явным кастом.
bormand 24.06.2012 21:52 # 0
Вы же не кастуете явно указатель на дочерний класс в указатель на родительский?
Или int в double в выражениях?
Так что неявный каст это не абсолютное зло.
interested 24.06.2012 22:01 # 0
Но не C++ way ;)
Неявный каст это из C. C++ более вежливый язык.
bool ok = state; Где здесь C++? :)
А вот где: bool ok = static_cast<bool>(state); :D
bormand 24.06.2012 21:24 # 0
Если назначение оператора bool() очевидно - то каст не нужен, он понятности не добавит.
Если же назначение оператора bool() не очевидно - то такой оператор не нужен. И каст тоже.
defecate-plusplus 24.06.2012 21:29 # 0
это у него на /W3 на пустом месте вырастает ворнинг C4800: 'type' : forcing value to bool 'true' or 'false' (performance warning), в котором они официально заявляют, что все три указанных мной преобразования не спасут: уou can add "!=0" to the expression, which gives the expression type bool. Casting the expression to type bool will not disable the warning, which is by design.
bormand 24.06.2012 21:44 # 0
defecate-plusplus 24.06.2012 22:04 # +1
просто ворнинг они не хотят убирать by design, вот и все
обычное дело для microsoft с ихними wontfix
interested 24.06.2012 21:33 # 0
А про is<Smth>(), конечно верно. static_cast говорит лишь о желании создать один тип из другого.
carsten 25.06.2012 15:19 # 0
Я, может быть, чего-то недопонимаю, но ведь С++ как раз был изначально спроектирован как суперсет С с "вселенским разумом" который для нас behind the scenes реализует все типы и все базовые преобразования между классами (родитель-потомок).
Т.е. я понимаю там, надобность введения reinterpret_cast<>, чтобы реализовывать какие-то хаки/общаться со старым кодом. Но вот зачем отдельные static_cast и dynamic_cast, мне не понятно. Возможно я не учитываю какую-то деталь. По-моему, компилятор владеет достаточной информацией, чтобы самому понять, какой тип каста должен быть, а читающему код и так очевидно. С++ сам за меня реализует все VTable и внутреннюю реализацию и много прочей байды (в отличие от С) -- я об этом не должен задумываться. Так почему же С++ заставляет задумываться о "динамичности" каста? Возможно, конечно, тут что-то влияет на производительность интерпретации шаблонов.
defecate-plusplus 25.06.2012 15:27 # 0
carsten 25.06.2012 15:40 # 0
Опять же, я могу ошибаться где-то.
TarasB 25.06.2012 15:52 # 0
carsten 25.06.2012 16:11 # 0
carsten 25.06.2012 16:23 # −2
C-style каст по своему определению (ибо это C-style) -- это reinterpret_cast для указателей, но static_cast для примитивов типа int <--> bool
Вместо же dynamic_cast и static_cast ввёл бы один общий cast<> с дополнительным аргументом-флагом: cast<Derived, NO_RUNTIME_CHECK> и cast<Derived> (синоним к cast<Derived, DO_RUNTIME_CHECK>)
Возражения?
defecate-plusplus 25.06.2012 15:56 # 0
очень даже не сомнительный - у меня вышло в 50 раз быстрее
http://pastebin.com/49RQKi0w
carsten 25.06.2012 16:07 # 0
defecate-plusplus 25.06.2012 16:23 # +1
существует крайне мало случаев, когда без него не обойтись
обычно злоупотребление динамик кастом свидетельствует об архитектурной ошибке
а синтетический пример показывает, что 1 динамик каст в 50 раз медленнее 1 такого же статик каста
о чем флейм? что все касты заменить на c-style? этого не будет
ты в компайл-тайм не сможешь выловить 100% случаев совместимости типов и нахождения в нужном месте в иерархии - даже в линк тайме не сможешь, потому что всегда есть возможность написать dll, о которой никто ничего не знает на этапе компиляции твоего приложения
а делать пессимизации и все передачи указателей/ссылок на объекты просеивать через сито динамик-каста - нет нет нет
carsten 25.06.2012 16:29 # 0
defecate-plusplus 25.06.2012 16:42 # 0
отдельные статик каст и динамик каст - первый приводит типы как считает нужным в компайл-тайме (и только в нем), второй лезет в иерархию классов и пытается там найти ответ в рантайме (быть может какой нибудь оптимизатор найдет в компайл-тайме, но на это рассчитывать нелепо)
при этом первый работает как бы с любыми типами, второй только со ссылками и указателями.
в режиме работы с ссылкой неуспешное приведение dynamic_cast сгенерирует исключение std::bad_cast, с указателями - нулевой указатель
неуспешное приведение static_cast приведет к ошибке компиляции
эти отличия не убеждают?
carsten 25.06.2012 17:08 # 0
Нет, полная каша же, и я нигде так и не увидел оправдания ей. См. http://govnokod.ru/10569#comment144035
defecate-plusplus 25.06.2012 17:12 # 0
какое компилятор должен принимать решение, если я напишу (SomeType *)ptr?
в какое время он это обязан делать (компайл тайм, рантайм)? будет ли единство?
carsten 25.06.2012 18:19 # 0
в какое время он это обязан делать (компайл тайм, рантайм)?
Как я написал выше в коменте, т.к. это С-style, то и кастовать в "идеальном С++" оно должно было бы как С, то есть как reinterpret_cast в общем случае, или как static_cast, если ptr имеет тип void*. То есть компайл-тайм.
Чтобы был райнтайм, в "идеальном С++", который проектировал бы я, использовался бы cast<> с дополнительным флагом по желанию, при котором можно отключить рантайм-проверку типов (для даункаста если хочется супер-производительности).
В остальном это забота компилятора определять, какой тип каста нужен.
Они "идеологически разными" вам кажутся только потому что вы привыкли к ним в С++. На самом деле они redundant и messy.
interested 25.06.2012 18:55 # 0
Два разных даже удобнее: сразу видно о чём речь. А так бы нам ещё во флаги всматриваться, да пытаться понять логику компилятора, где он какой каст вставил. И так тяжело бывает следить за неявным кастом, а по вашей логике ещё и за явным глаз да глаз. Неудобно ужасно. Неуважение к программисту какое-то.
Это всё равно, что команды распараллеливания в OpenMP: зашарашат, а потом думают: "Почему не работает?", а оказывается компилятор подтуповат, не уловил задумку клёвого прогера и "не так" распараллелил.
Компилятор должен быть как можно глупее. Только самое лобовое делать: ать-два, ать-два. Избавлять программиста нужно от необходимости выполнять монотонную работу, копипасты, например.
bormand 25.06.2012 19:12 # +3
Есть такой, называется ассемблер.
> Избавлять программиста нужно от необходимости выполнять монотонную работу, копипасты, например.
И в ассемблере как раз есть макросы.
interested 25.06.2012 19:25 # 0
carsten 25.06.2012 19:12 # 0
В том, что для отключения функции, не нужно вводить новый интерфейс. Напр. в D буфер в стеке по умолчанию инициализируется нулями. Если хочешь это отключить (что нужно редко, где-нибудь в цикле пару раз на всю программу) -- пиши "= void" в конце. Если бы D проектировал индус Страуструп, то он бы тут забацал два примитивных типа unsafe_byte_array и safe_byte_array и ещё бы заставлять кастовать между собой через ещё один интерфейс :) И его адепты бы восхваляли "очевидный и простой синтаксис".
>Два разных даже удобнее: сразу видно о чём речь
А зачем тебе нужно это видеть? Прематуре оптимизатион. Вот если окажется, что где-то есть даункаст в очевидный тип, и в этом боттлнек согласно профайлеру -- тогда задумывается и вставляй флаг, отключающий рантайм-проверку. В остальных случаях тип каста должен определяться самим компилятором, а не вручную программистом. Может быть ещё и методы скажете дёргать из VTable'а вручную? В чём тогда пойнт использовать С++, а не С?
>А так бы нам ещё во флаги всматриваться
Т..е., по вашему NO_RUNTIME_CHECK один раз в год -- менее очевидно, чем static_cast с размазанной семантикой?
>Компилятор должен быть как можно глупее
И поэтому нужно писать static_cast<bool>, хотя компилятору и так очевидно, что это статический каст? Тут совсем не нужно компилятор делать суперумным.
>Избавлять программиста нужно от необходимости выполнять монотонную работу
Да, вроде как писать static_cast и dynamic_cast там, где можно было бы написать просто cast (как единый притимив, в целом противопоставляемый С-style-касту).
carsten 25.06.2012 19:20 # 0
>а по вашей логике ещё и за явным глаз да глаз
NO_RUNTIME_CHECK как раз кричит во весь код, что здесь оптимизация, отключили проверку: может быть креш, если что-то поменяем. При static_cast<WrongDerivedClass*> нихрена это не очевидно.
defecate-plusplus 25.06.2012 19:45 # 0
> NO_RUNTIME_CHECK
удачи, кастуй очевидные вещи в рантайме, зануляй в стеке буферы по умолчанию
> работа компилятора определять
ну так используй c-cast, в чем проблема, улучшатель
> с размазанной семантикой
> нихрена это не очевидно
если ты чего то не осилил - это твои личные проблемы
учить тебя тут уму разуму никто не собирается
курсы С++ для начинающих - в другом месте
carsten 25.06.2012 19:52 # 0
Ну если тебе всё и всегда очевидно, то зачем тебе вообще типизация? Используй void*, гений.
defecate-plusplus 25.06.2012 20:03 # 0
а у тебя очевидный батхёрт от такой простой вещи
я тебе по секрету скажу, что даже static_cast в нормальном приложении должен быть серьезно оправданным случаем
carsten 25.06.2012 20:11 # 0
>и никогда const_cast и dynamic_cast
Гы. А что же ты тут тогда лопочешь про оверхед в рантайме, если ты их почти не используешь? Типичный premature optimization головного мозга.
И я ничего не говорил о том, что кастование само по себе это ух как здорово.
>static_cast/reinterpret_cast
>ололо, как раз для наложения сишных структур на принятый из сети буфер
Сенсация: здесь специальный оператор кастования на уровне языка не нужен, обычный уже существующий C-style подойдёт. Не нужно вводить кучу примитивов на каждый чих -- тем более что сишные структуры как раз требует сишного подхода.
defecate-plusplus 25.06.2012 20:17 # +1
о том, почему один менее безопасный сишный каст превратился в три более безопасных ты почитаешь в открытых источниках
в этом топике я приводил пример
carsten 25.06.2012 20:26 # 0
Это до тебя туго доходит. Ты опять говоришь мне о текущей реализации С++, а я говорю о том, как *следовало бы* сделать. Следовало бы reinterpret_cast, static_cast<T*>(void*) и static_cast<int> объединить с C-style-cast (повторяю для тупых -- не так, как оно реализовано сейчас в С++!), противопоставив C++style, class-based cast<>, где можно отключить рантайм-проверку для производительности. Здесь всё прекрасно очевидно, что компилятор вставит. Закрывая дыры Си, _cast-стайлы вводят собственные дыры, так что я не вижу особой причины радоваться.
carsten 25.06.2012 20:06 # −1
Ну конечно если ты уже замусорил свою голову этим полупьяным бредом -- то оно тебе очевидно.
Я же просто говорю про изначально более чистый дизайн (по моему мнению).
В дизайне ПХП тоже много пьяного бреда, и я уверен, ты бы так же защищал ПХП, выучив все corner cases -- подменяя аргумент о хорошем дизайне аргументом о том, что ты осилил выучить этот дизайн -- следовательно, он хорош. Молодец.
interested 25.06.2012 19:28 # 0
TarasB 25.06.2012 19:48 # +2
interested 25.06.2012 22:35 # 0
Там где люди ставят каст, означает, что компилятор уже не в силах что-нибудь разрешить. Люди в здравом уме такой аншлаг, как static_cast<bool>(int) не пишут. Зачем они нужны трёх типов я уже здесь где-то написал: в какой момент возможно разрешить валидность кастовки.
Вам что сто типов каста нужно, раз вы флаги навешиваете?! Или вы плохо понимаете семантику слов static_ и dynamic_? Какая размазанность?
Заканчиваем балаган. Никакого супер-гавка.
bormand 26.06.2012 05:21 # 0
Крестосрач считаем завершенным?
rat4 26.06.2012 08:57 # +1
bormand 26.06.2012 09:01 # 0
interested 26.06.2012 09:56 # 0
Так... Надо писать письмо в комитет по стандартизации, чтобы в новом C++ 2014 к олимпиаде в Сочи const_cast убрали.
bormand 26.06.2012 10:09 # 0
В остальных 99.9% случаях const_cast юзают или по дурости и неумению пользоваться const'ами или для затыкания дыр во внешних либах, автор которых не осилил const'ы.
interested 26.06.2012 10:26 # 0
Сложно себе представить жизненную ситуацию, где внутри совместных интерфейсов может возникнут необходимость нарушить такой важный контракт.
Сами посудите.
Константность означает, что поставщик запрещает вам вмешиваться во внутреннюю структуру поставки, потому что это может вызвать нарушение согласованности. Если вы можете снять const, нарушить контракт, и при этом оставить поставщика и поставку в согласованном состоянии, значит либо вы знаете достаточно много о внутреннем устройстве поставщика, либо делаете это небезопасно из-за несогласованности контракта сдачи-приёмки.
И то, и другое -- это нарушение архитектуры. Нужен адаптер, врепер -- что угодно, что разрешит конфликт контракта, либо у вас нарушена инкапсуляция и нужно пересмотреть разбиение на классы.
bormand 26.06.2012 10:36 # 0
Надеюсь, что библиотек, в интерфейсах которых не расставляют const уже не осталось.
interested 26.06.2012 10:53 # 0
bormand 26.06.2012 15:07 # +2
> Существуют неизменные библиотеки для численного анализа.
У вас есть код этих библиотек? Если есть - садитесь и расставляйте const'ы. Ими вы ничего не испортите - ни самой библиотеки, ни софта который ей пользуется. За пару дней, думаю, управитесь.
Если кода нет, и из достоверных источников вам известно, что функция не портит аргументов (например так сказано в документации) - смело правьте ашку, дописывая в нее const.
Если же кода нет, и вы не уверены в том, что эти функции ничего не модифицируют - то какого #$% вы вообще используете const_cast!?
interested 26.06.2012 15:38 # 0
Гораздо быстрее в своей конкретной программе поставить два каста в нужном месте, где я уверен, что всё будет хорошо.
Какой смысл трогать библиотеку и заниматься чпоканием констов в сотне местах и просто тереть пальцы? Тем паче об исходный код, пусть они даже и есть. Я же его не править, а переиспользовать хочу.
interested 26.06.2012 15:47 # 0
bormand 26.06.2012 15:57 # 0
Ну если либа под свободной лицензией, то почему бы не принести пользу сообществу, расставив в ней const'ы? Тогда таких библиотек станет еще меньше ;)
> Гораздо быстрее в своей конкретной программе поставить два каста в нужном месте, где я уверен, что всё будет хорошо.
Искренне надеюсь, что эта уверенность порождена анализом исходников, а не тестированием.
> Чтобы не нагружать и без того сложные вещи ещё и адаптерами
> поставить два каста
Два wrapper'а сильно усложнят программу?
interested 26.06.2012 16:13 # 0
Если написано, что данные по такому-то пришедшему указателю не меняются, то можно смело кастовать ссылку на внутренние данные в неконстантную для передачи в функцию.
Да, wrapper длиннее каста. Кроме того, каждый "новый" код -- это, собственно, и есть wrapp старого кода, который я переиспользую, в нечто новое.
Вы явно потеряли мысль: не исправить, а использовать то, что сделано.
bormand 26.06.2012 16:24 # 0
Ну если этот код и есть высокоуровневая обертка над NR - пусть будут const_cast'ы ;) Лишь бы в прикладном коде их не было.
HaskellGovno 26.06.2012 09:07 # 0
Хочу:
А ещё окромя static_cast и dynamic_cast хочу agree_cast, например:
Кстати, unconst(a) я делал на шаблонах, добротно получилось.[/вброс]
rat4 26.06.2012 09:19 # +4
interested 26.06.2012 09:47 # 0
Та самая кошка!
Новый язык программирования:Do.
Пишешь Do, и компилятор компилирует это в прогамму :)
bormand 26.06.2012 09:43 # 0
И правильно. В том 0.1% случаев когда он действительно нужен, а не притянут за уши к кривой архитектуре - его можно и написать.
HaskellGovno 26.06.2012 09:17 # 0
dynamic_cast не всегда работает, поэтому придумали такой костыль.
interested 25.06.2012 16:52 # −3
Относительно кастов... static_cast -- разрешается на стадии компиляции. dynamic_cast -- разрешается во время исполнения, reinterpret_cast --разрешается никогда. const_cast -- для обхода запрета.
carsten 25.06.2012 17:00 # +1
Да, и именно поэтому Страуструп при создании назвал его C with Classes. И поэтому ввёл совместимость на уровне исходного кода, хотя мог ввести просто ABI/API совместимость (как в C# сделали), избавив свой гениальный язык с "преимуществами ООП" от кучи кривых хаков, введённых в первую очередь потому, что С++ задумывался именно как суперсет С.
interested 25.06.2012 17:22 # 0
interested 25.06.2012 17:29 # 0
carsten 25.06.2012 18:40 # 0
rat4 24.06.2012 21:16 # +1
interested 24.06.2012 21:21 # −2
rat4 25.06.2012 08:00 # 0
interested 25.06.2012 09:19 # 0
Это наследие от С.
Но у хороших С++ программистов типизация строгая. И они помидоры в огурцы не кладут.
roman-kashitsyn 25.06.2012 09:22 # +4
defecate-plusplus 25.06.2012 09:39 # +2
если сущность из коробки предоставляет operator bool, нелепо везде писать static_cast<bool> для нее
если встроенный тип умеет себя кастить, надо этим пользоваться
если объект имеет operator bool (), надо этим пользоваться
code bloat нужен только для параноидального ПО, когда неумелые преобразования типов приводят к неожиданным для программиста ситуациям - ну так и С++ не подходящий для этого язык
однако в 99.99% программ общего назначения (а с++ как раз язык для таких программ) параноидальность не нужна - потому что увеличивается время разработки и ухудшается читаемость программ, а профита никакого - в элементарнейших ситуациях, таких как кастинг int к bool, даже начинающий программист понимает что происходит, это соответствует стандарту и даже не приводит к UB
не стоит уродовать возможности языка и тем более говорить что это всё С, а не С++
если почитать стандарт, во многих случаях комитет даже не парится с записью с-каста как static_cast - потому что это короче, проще и опытному программисту не доставляет проблем
пример с double d = 2.L/1 - это от лени дописать .L в любом из операндов? если надо делить две переменных, то достаточно тоже один операнд скастить
в пост призывается тарас с безопасными приведениями типов
TarasB 25.06.2012 09:45 # 0
Не согласен.
bormand 25.06.2012 09:56 # 0
Полностью поддерживаю. В тех случаях где каст в бул очевиден - все понятно и без статик_каста. В тех случаях где каст не очевиден - каст не нужен ни в той ни в другой форме, и лучше применять другие средства.
interested 25.06.2012 10:18 # 0
bormand 25.06.2012 10:24 # 0
interested 25.06.2012 10:58 # 0
BaseClass* B = new DerivedClass();
DerivedClass* A = (DerivedClass *)B;
bormand 25.06.2012 11:07 # 0
interested 25.06.2012 11:11 # −2
interested 25.06.2012 11:12 # 0
defecate-plusplus 25.06.2012 11:31 # 0
http://govnokod.ru/10569#comment143947
а динамик каст нельзя заменить скобками, потому что скорее всего будет вызываться reinterpret (если компилятор не посчитает типы совместимыми), реже - статик
TarasB 25.06.2012 11:42 # 0
interested 25.06.2012 10:09 # 0
roman-kashitsyn 25.06.2012 10:24 # 0
interested 25.06.2012 11:00 # 0
defecate-plusplus 25.06.2012 10:30 # +2
например,
или вопрос был зачем вместо c-cast определили static_cast/reinterpret_cast/const_cast?
TarasB 25.06.2012 10:49 # 0
defecate-plusplus 25.06.2012 11:28 # 0
http://ideone.com/M6mEG
interested 25.06.2012 10:55 # 0
static_cast сообщает больше о действии, чем c-cast и тем паче неявная кастовка типа.
Хороший тон, сообщать, по-возможности, полную информацию.
А то смотришь какую-нибудь передачу "совершенно секретно", а там говорят: "наука не может ответить на вопрос о том, почему период обращения Луны вокруг своей оси равен периоду обращения вокруг Земли". Это нехорошо.
Конечно, можно сказать, что лишний каст int к bool запутывает. Это, наверно, так. Но если state -- это пользовательский тип, который нужно привести к bool, например для тоже полиморфизма символа, то так писать и нужно. И мой пример со static_cast<double> как раз и был нацелен в примитивном виде на демонстрацию сложности ощущения неявного преобразования.
Не следует человека заставлять думать лишнего над тем, над чем он думать не должен.
Говорить нужно правду, только правду и всю правду.
А во-вторых, менять по ходу доказательства теоремы крест на звезду, а звезду на точку -- моветон. Так же и в коде менять один вид преобразования типа на другой в разных местах программы -- неприлично. Это не нанесёт вреда читающему, но осложнит понимание.
Хотите c-cast и неявный каст? Добро пожаловать в C! Короткий код -- высокая производительность.
C++ язык более читаемый с элементами обратной совместимости, чтобы определённое множество программистов быстрее смогло на нём создавать программы.
bormand 24.06.2012 21:14 # 0
interested 24.06.2012 21:20 # 0
glook 26.06.2012 09:01 # 0
Наставили минусов и нафлудили.
Хехе.
PS: reinterpret_cast рулит!
interested 26.06.2012 09:53 # 0
Тут уже придумали: Вольт -- суперкаст!
Сам всё определяет своим супервзглядом, оптимизирует всё в суперскорость и отгоняет программистов супергавком!
guest 26.06.2012 17:03 # −2
interested 26.06.2012 17:38 # 0
Ну откуда будет существенный статический каст в Java, если все объекты наследуют одному, а самих объектов нет, есть только ссылки, которые всегда безболезненно одна в другую превращаются? Следить, чтобы объект в int не кастанули? Ну разве что... И reinterpret_cast в Java бессмысленный, потому что там не может возникнуть непонятной последовательности битов, там VM всё про всех знает.
Ну и зачем Java много кастов?
И так, я полагаю, во всех ваших "здравых" языках. Они просто не сталкиваются с ситуациями, с которыми можно столкнуться в C++, потому им и касты сложные не нужны.
carsten 27.06.2012 00:29 # −3
Я повторяю мою мысль -- если бы я был Страуструпом и я бы сочинял суперсет Си, то я бы оставил семантику си-каста как он есть (как раз одно из тех мест, где совместимость с Си порушили) -- т.е. объединил бы static_cast<> и reinterpret_cast. А для классов заюзал бы один общий cast(). Остальное не наша забота.
Если уж на то пошло, почему С++ позволяет виртуальным методам вызываться динамически без указания большими буквами, что это рантайм-вызов? Вполне С++ way было бы вместо obj->foo() писать dynamic_call obj->foo()! А если не хочешь виртуально -- то вызывай так: static_call obj->foo()! Подумаешь, что во втором случае может крешануться, потому что вызван не на тот derived-class! В учебнике написано, что в целом такая конструкция более безопасная, чем устарелый, никчёмный C-style call. Гы.
bormand 27.06.2012 05:27 # 0
> т.е. оверхед negligible
Вы видите взаимно-однозначное соответствие между этими двумя высказываниями?
HaskellGovno 27.06.2012 07:20 # 0
interested 27.06.2012 11:46 # 0
Объясним третий раз.
static_cast -- это любое преобразование типа, которое нужно разрешить на этапе компиляции.
То есть, компилятор в определённом месте, где стоит static_cast должен вывести один тип из другого.
Это нужно, например, чтобы разрешить сложности с полиморфными символами на этапе компиляции. С тем же делением, нужно указать компилятору, что пришедшие два целых числа нужно трактовать как с плавающей точкой и вызвать нужную реализацию символа деления.
Бывают более экзотические случаи с необходимостью приведения типа в аргументах шаблонных функций/методов. Использование "даункаста" в static_cast нужно просто для того, чтобы на этапе компиляции воспользоваться преимуществами статической типизации и определить: а вообще возможно такое присвоение? А то вдруг я где ошибся, скомпилировал, думаю, что всё ок, а там два класса из разных иерархий.
dynamic_cast -- производит проверку совместимости контрактов в ран-тайм. То есть, уже недостаточно нам информации периода компиляции, чтобы решить этот вопрос. Программа может быть собрана из разных динамических библиотек, с разными контрактами и т.д. Но разрешимыми. И вот, в некоторых местах возникает необходимость перейти в расширенный контракт, чтобы переиспользовать код.
reinterpret_cast -- вообще ничего не проверяет. Он используется, если уже никакой информации получить не удаётся. Вам в каком-то MPI мессадже упали биты о.О И чё? Кто скажет вам, что это такое? Строка аль массив чисел, аль еШо чего-нибудь. Никто! Вам приходится надеяться, что данные пришли доверенные и не побились. Хеш сошёлся -- пошёл каст. Он говорит: думай об этих битах, как массиве целых! Ок! Но проблемо!
Три разных уровня возможно ошибки возникновения в коде: на этапе компиляции (можно проверить статическую типизацию), во время ран-тайм (можно выбросить исключение, если контракт неожиданный), во время исполнения, но без проверки (а потому что узнать неоткуда).
interested 27.06.2012 11:48 # −1
carsten 27.06.2012 00:29 # 0
Ну так все эти ситуации в С++ -- от воспалённого мозга. Сами придумали проблему, сами решили. Потом сидят довольные -- какие мы умныя :)
roman-kashitsyn 27.06.2012 00:38 # +3
bormand 26.06.2012 17:42 # 0
interested 26.06.2012 21:37 # 0
Вот она -- сила... пенопласта... :)
bormand 27.06.2012 05:28 # 0
interested 27.06.2012 11:52 # 0
glook 27.06.2012 11:56 # 0
Жесть, народ!
roman-kashitsyn 27.06.2012 00:36 # +1
А ещё меня плющит от кода, набранного пропорциональным шрифтом