И>int* p = NULL;
И>int a = 1, c = 10;
И>int b = (p? *p : c) / 100;
И>
Ну так, <censored> нам кабанам, обобщим, и научим тупой С++ работать с nullable
template <typename T>
class nullable
{
public:
nullable(T* p ,T val )
{
res = p ? *p : val ;
}
T res;
};
int main(int argc, char* argv[])
{
int* p = NULL;
int a = 1;
int c = 10;
p = &a;
b = nullable<int>(p,c).res / 100;
return 0;
}
Здравствуйте, Игoрь, Вы писали:
И>Мы сейчас говорим о конкретных языках или "вообще"? Если говорить "вообще", то я могу согласиться, что в С++ константность — это сбоку бантик, который легко снимается конст-кастом. И это все дело можно было бы сделать намного лучше, делая сейчас и не думая об обратной совместимости. С этим я как бы и не спорю. Но только при чем здесь C++ и C#?
C# тут действительно не причем.
Тут С++ мочат
И>И с этим я не спорю, и то, что они могли сделать нормально — согласен, но сейчас есть то, что есть. А то что есть не особо лучше того, что есть в С++.
По своему опыту могу сказать что таки сильно лучше.
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Здравствуйте, WolfHound, Вы писали:
WH>Тут С++ мочат
Пытаются, сравнивая его с C#
И>>И с этим я не спорю, и то, что они могли сделать нормально — согласен, но сейчас есть то, что есть. А то что есть не особо лучше того, что есть в С++. WH>По своему опыту могу сказать что таки сильно лучше.
Ну так может ты приведешь конкретные примеры из твоего опыта, особенно интересны связанные с mutable/immutable? Потому что я серьезных преимуществ пока не вижу, кроме как иногда хочется в С++ использовать что-то более легковесное а-ля const_string, только не как замену string. С другой стороны и в C# иногда хочется использовать какой-то аналог string с возможностью записи.
Здравствуйте, criosray, Вы писали:
C>Здравствуйте, criosray, Вы писали:
C>>То, как сделано в С# — ГОРАЗДО лучше. Строки обязаны быть immutable по той причине, что: C>>var str = "abc"; C>>var str2 = "abc2"; C>>ссылаются на один и тот же участок памяти str == str2 true.
C>Опечатка. str2 = "abc" конечно же.
Кстати, а что мешает и варианты "abc" и "abc2" хранить в одной области(имеется ввиду сами буфферы, объекты будут разными в любом варианте)?
Длина заключена в объекте(а не определяется положением терминирующего символа), при этом строки никогда не будут изменены.
Так ли это в реале, не знаю, но ничего не мешает так устроить.
Новости очень смешные. Зря вы не смотрите. Как будто за наркоманами подсматриваешь. Только тетка с погодой в завязке.
There is no such thing as a winnable war.
Здравствуйте, Игoрь, Вы писали:
И>Пытаются, сравнивая его с C#
Ты меня с кем-то путаешь.
И>Ну так может ты приведешь конкретные примеры из твоего опыта, особенно интересны связанные с mutable/immutable?
С immutable всегда проще.
Причем это не только строк касается.
Особенно если язык заточен на работу в этом стиле. Тут
я уже приводил пример кода работающего исключительно с неизменяемыми данными.
Даже если этот код оставить на немерле но переписать так чтобы AST изменялся по месту получится серьезное усложнение.
Со строками все не так печально но там тоже хватает головной боли особенно в многопоточной среде.
И>Потому что я серьезных преимуществ пока не вижу, кроме как иногда хочется в С++ использовать что-то более легковесное а-ля const_string, только не как замену string.
И создать еще одну строку...
И>С другой стороны и в C# иногда хочется использовать какой-то аналог string с возможностью записи.
Зачем?
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Здравствуйте, 0xC0000005, Вы писали:
C>Здравствуйте, criosray, Вы писали:
C>... C>>Специально для Вас выделил ключевое.
C>Вы так умело затёрли вашу цитату, выделю главное, и больше не мозольте эту тему, вы ПИСАЛИ:
C>
C>Интерфейс по определению ничего не может делать. Интерфейс это чисто контракт. Не выдумывайте своих определений общеизвестных терминов.
C>Потом вы пишете
C>
C>А никто и не утверждал, что интерфейс является полным контрактом класса
C>Не будем углубляться в аспекты русского языка, но если к примеру колесо это неотьемлемая часть машины (давайте не разводить демагогию о том какие бывают машины), то нельзя написать: C>Колесо — это чисто машина. C>Надеюсь в этот раз я вас не запутал и привёл нормальные доводы.
Мне кажется, ты не прав. Например, я утверждаю что Подработка это чисто доход. При этом я не утверждаю, что подработка это полный мой доход. Это часть полного дохода.
Luck in life always exists in the form of an abstract class that cannot be instantiated directly and needs to be inherited by hard work and dedication.
Я знаю только две бесконечные вещи — Вселенную и человеческую глупость, и я не совсем уверен насчёт Вселенной. (c) А. Эйнштейн
P.S.: Винодельческие провинции — это есть рулез!
Здравствуйте, WolfHound, Вы писали:
И>>Потому что я серьезных преимуществ пока не вижу, кроме как иногда хочется в С++ использовать что-то более легковесное а-ля const_string, только не как замену string. WH>И создать еще одну строку...
А в чём проблема? Реализаций строк можно иметь хоть мильён. Работа с таким зоопарком просто и складно унифицируется набором свободных функций типа такого:
template<typename Str1_, typename Str2_> void assign(Str1_ *, const Str2_ &);
template<typename Str_> int getLength(const Str_ &);
template<typename Str1_, typename Str2_> int getSubstring(Str1_ *, const Str2_ &, int pos, int length);
Некоторое исключение составляют ASCIIZ-строки, с остальными особых заморочек нет.
Я знаю только две бесконечные вещи — Вселенную и человеческую глупость, и я не совсем уверен насчёт Вселенной. (c) А. Эйнштейн
P.S.: Винодельческие провинции — это есть рулез!
Здравствуйте, WolfHound, Вы писали:
И>>Ну так может ты приведешь конкретные примеры из твоего опыта, особенно интересны связанные с mutable/immutable? WH>С immutable всегда проще. WH>Причем это не только строк касается. WH>Особенно если язык заточен на работу в этом стиле. WH>Тут
я уже приводил пример кода работающего исключительно с неизменяемыми данными. WH>Даже если этот код оставить на немерле но переписать так чтобы AST изменялся по месту получится серьезное усложнение.
Не, ну хорошо, кто бы спорил. Раз подходит для каких-то задач, замечательно. Мне такое пока не нужно.
WH>Со строками все не так печально но там тоже хватает головной боли особенно в многопоточной среде.
Вот как раз с многопоточностью и строками я как-то никогда проблем не имел.
И>>Потому что я серьезных преимуществ пока не вижу, кроме как иногда хочется в С++ использовать что-то более легковесное а-ля const_string, только не как замену string. WH>И создать еще одну строку...
Иногда для оптимизации и не такое приходится делать, например выкидывать std::vector, из-за того, что тот свой буфер зануляет.
И>>С другой стороны и в C# иногда хочется использовать какой-то аналог string с возможностью записи. WH>Зачем?
Например есть строки размером от 50КБ до 5МБ, надо найти и вырезать какие-то куски без лишних релокейшинов. Все что мне нужно — хоть простой набор алгоритмов над текстовым writable буфером.
Здравствуйте, WolfHound, Вы писали:
WH>Здравствуйте, jazzer, Вы писали:
J>>Там в полный рост зоопарк компиляторов. J>>Это можно записать в недостатки С++ как платформы, но не С++ как языка. WH>Далеко не только. WH>Там тонны костылей для извлечения метаинформации. WH>Куча костылей для того чтобы сделать какой нибудь трюк. WH>Короче почти все решения из серии через зад автогеном.
Ну, если ориентироваться только на нормальные компиляторы, то костыли эти достаточно прямые и простые, а веселье начинается, когда пытаешься заставить это работать на всех компиляторах, включая уродцев типа мс-шестерки и сана. Наверное, если бы AT&T изначально владела языком и вкладывалась в него, как Сан с явой или Мелкософт с шарпом, не допуская зоопарка, то такого не было бы, но тогда другие времена были, у всех языков была масса диалектов (да и сейчас, вон посмотри на хаскель).
Но главное то, что все это внутри библиотеки и пока тебе не понадобилось туда нырнуть, пользоваться библиотекой легко и приятно и зоопарка под капотом не видно. И, имхо, то, что на таком старом языке можно написать библиотеки уровня Boost.Fusion и Boost.Proto, говорит только в пользу этого языка.
Хотя, конечно, неплохо было бы иметь все это (метаинформацию) встроенным непосредственно в язык, с этим никто не спорит.
Но метаинформации в С++ не было изначально, просто потому что он — наследник С, а там это чуждая концепция.
Сам понимаешь, в язык с таким наследием добавлять новые фичи нужно очень аккуратно, иначе С++ кончит как D, который сам с собой не совместим.
Так что что есть, то есть.
Конечно, она в том или ином виде будет добавлена в язык, но в каком именно — это большой вопрос, которым нужно заниматься, а на это у комитета банально нету времени, потому что гораздо больше народу требуют многопоточности и сборки мусора (последнюю так и не успели вставить в С++0х).
Собственно, то, что будет с С++ дальше, можно увидеть здесь: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2009/n2869.html (прокрути до "Not ready for C++0x, but open to resubmit in future").
J>>Имхо, это совершенно некритично, и никто не мешает к этому чистому контракту привернуть пару невиртуальных функций — это никак на чистоте контракта не скажется, так как то, что было чисто виртуальным, им и останется. WH>Не согласен. WH>В принципе можно иметь реализацию по умолчанию но возможность перекрытия должна быть в обязательном порядке.
Так она и есть, или я тебя не так понял.
Плюс контракт — это гораздо более широкое понятие, чем интерфейс. И в этом смысле класс С++ подходит для выражения концепции контракта лучше, чем просто интерфейс, потому что интерфейс редуцирует контракт до набора (причем фиксированного!) функций, что не всегда оправдано. WH>Иначе могут быть проблемы связанные с тем что конкретную реализацию таки не устраивает реализация по умолчанию. WH>Именно по этому вообще любое наследование реализации зло.
В С++ наследование — это не только наследование в классическом понимании ООП.
Там, например, наследуются типы/тайпдефы, и тому подобное. Вспомни CRTP хотя бы.
WH>Одним из приемлемых вариантов было бы что-то вроде этого:
WH>
WH>Миксин может реализовывать один или несколько интерфейсов и требовать реализации некоторых интерфейсов.
Это можно и сейчас dynamic_cast-ом сделать.
WH>К миксину привести нельзя.
Почему? В чем смысл такого ограничения?
WH>Таким образом можно получить все плюсы множественного наследования без его минусов.
А чем тебя не устраивает подход ATL/WTL?
Он, кстати, позволяет частичную реализацию интерфейса — как насчет твоих миксинов? Они должны реализовывать интерфейс полностью или частично тоже сойдет? И если да и если ты хочешь собрать свой класс из вот таких вот частичных реализаций, ты разве не поимеешь все проблемы множественного наследования, которые есть сейчас? А если нет — так уж ли оно полезно, если вспомнить про какой-нть интерфейс OLE-объекта с 53 функциями?
J>>+1. Но это спор не о языках, а о библиотеках. WH>Скажи это 0xC0000005
В смысле? Я не помню всех кодов ошибок, расшифруй, плиз
J>>+1. Макросы Немерле было бы очень здорово поиметь в плюсах. Много проблем бы сразу ушло. WH>Макросы немерла имеют своих тараканов. А именно они совершенно не формализованы и осень сильно подвязаны на конкретную реализацию конкретного компилятора. WH>Но этот недостаток можно устранить. WH>Правда серьезной переработкой языка и компилятора.
О чем и речь
Так просто наскоком такую подсистему в язык не добавить — цена ошибки слишком велика.
Для этой цели (обкатки концепций) такие молодые языки, как Немерле, подходят идеально, и их ценность в этом смысле сложно переоценить, и в этом их отличие от промышленных языков.
А вот когда обкатают и будет наработана достаточно большая база решений и, что более важно, граблей, тогда можно думать и о встраивании концепции в промышленные языки.
WH>Но не до конца. .NET собака такая под ногами со своей кривостью путается.
Прям как в С++
Ну, в общем, как я и говорил энтузиастам дотнета сколько-то там лет назад ("У вас тяжкое наследие, а у нас все свежее и необремененное" — "Ничего, поговорим лет через 10"), как мы скрипим от унаследованных недостатков С++, так и явисты/дотнетчики заскрипят, когда осознают, что их новые свежие языки-платформы неидеальны, и не упрутся в их пределы и в никуда не девшиеся требования совместимости с существующим кодом (а в случае явы/дотнета — еще и с существующим байт-кодом).
А особенно когда еще через лет появится какая-нть модная технология, про которую все будут говорить: "Это must have, она должна быть в любом нормальном языке по умолчанию, все остальные на помойку!" (как сейчас с рефлексией, сериализацией и т.п.) а явисты/дотнетчики будут чесать репу, понимая, что на их языках невозможно по-человечески эту фичу реализовать, потому что она не будет ни с чем совместима и сломает язык. И будут предлагаться библиотеки, дающие требуемую функциональность, а неофиты будут плеваться и называть их костылями, и будут показывать пальцем на какой-нть новый язык Ветч или Гед, в котором эта фича уже есть сразу и выглядит красиво и непротиворечиво (но это только пока ею не начали пользоваться достаточно широко — тут-то и будет собран урожай граблей, которых вначале видно не было).
Нету идеальных решений на свете.
Как говаривал Страуструп, есть два вида языков (шире — технологий): те, которые все ругают, и те, которыми никто не пользуется.
Так что у С++ есть свой хорошо известный набор проблем, есть не менее хорошо известный (и зачастую вполне удобный) набор средств по их устранению/недопущению/предупреждению, и профессиональные программисты вполне комфортно себя чувствуют, хотя это и не значит, что они не будут приветствовать усилия комитета по уменьшению этого набора.
Ну и у явы/дотнета/шарпа/немерле/etc есть свои проблемы и свои инструменты.
Let it be.
Здравствуйте, Геннадий Васильев, Вы писали: ГВ>Арифметику и логические операции можно добавить по вкусу.
Кстати, там лифтинг заработает?
Лифтинг — это когда все операторы, определенные для типа T, автоматически определяются для типа Nullable<T> — соответствующим образом, то есть возвращают Nullable<T>, который null, когда хотя бы один из операндов Null.
Но если какого-то оператора у T нет, то ошибка будет только при попытке вызвать аналогичный оператор для Nullable<T>, а не при попытке сконструировать Nullable<T>.
... << RSDN@Home 1.2.0 alpha rev. 677>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, Игoрь, Вы писали: И>Опять начинается путаница. Если мы говорим в пониманиии константности С++, то это неверно. Алгоритм требующий константности объекта, априори будет работать и для неконстантного объекта, просто из-за того, что константность более жесткое ограничение.
Да-да, вы как раз вносите путаницу. Конечно же, алгоритм, заложившийся на константность объекта, никак не сможет работать с неконстантым. Например, из константности мы можем вывести возможность не делать блокировок при обращении; можем полагаться на то, что хеш будет неизменным; много на что еще можем полагаться. Неконстантность ничего этого не даёт, поэтому алгоритмы на С++ невозможно оптимизировать подобным образом. И>С другой стороны, если мы в понятие константности строки включаем еще и фиксированное размещение ее в памяти или в каком-то сторадже. Ну да, там можно использовать какие-то оптимизации в виде хэш == адрес. Но таких алгоритмов раз два и обчелся,
Всё как раз наоборот — подавляющее большинство алгоритмов сильно выигрывает от константности. К тому же 90% строк в приложениях никогда не модифицируются — они применяются в семантике value типов. И>а кроме того ведь в таком подходе C# есть и недостатки. Например, если идет относительно активная работа с текстом, включая его изменения, то почему я должен на каждый чих создавать копию строки? Опять эффективность, но уже в другую сторону.
Если идет активная работа с текстом, что очень редко, то нужен совсем другой контракт. Для этого применяют StringBuilder.
... << RSDN@Home 1.2.0 alpha rev. 677>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, Eugeny__, Вы писали: E__>Кстати, а что мешает и варианты "abc" и "abc2" хранить в одной области(имеется ввиду сами буфферы, объекты будут разными в любом варианте)? E__>Длина заключена в объекте(а не определяется положением терминирующего символа), при этом строки никогда не будут изменены. E__>Так ли это в реале, не знаю, но ничего не мешает так устроить.
В Java именно так работает выделение подстроки.
... << RSDN@Home 1.2.0 alpha rev. 677>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, CreatorCray, Вы писали: CC>А если это не так (что скорее всего) то тогда получается что уже в качестве ключей их использовать упс... И память они уже не экономят...
Экономия памяти — ерунда. Шансов на то, что две строки совпадут — практически нуль.
Зато гарантированная константность позволяет использовать хеш строки в качестве части ключа.
... << RSDN@Home 1.2.0 alpha rev. 677>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, CreatorCray, Вы писали: C>>Это конечно все замечательно, но как это соотносится с обсуждаемым вопросом об immutable природе строк? CC>Это у тебя они все immutable. А реальный мир прекрасно живет и с mutable и c immutable строками.
Реальный мир имеет дело с двумя принципиально разными видами "строк".
Одни из них имеют value-type семантику, и, естественно, неизменны и постоянны.
Другие имеют семантику ref-type, и занимаются построением текстов.
В С++ по давней традиции, смешивают две эти сущности в одну. Итоговый результат одинаково плохо выполняет обе задачи.
... << RSDN@Home 1.2.0 alpha rev. 677>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, Sinclair, Вы писали:
CC>>А если это не так (что скорее всего) то тогда получается что уже в качестве ключей их использовать упс... И память они уже не экономят... S>Экономия памяти — ерунда. Шансов на то, что две строки совпадут — практически нуль.
Ну тут просто от криоса крику было про экономию памяти: 3 байта вместо 6ти.
S>Зато гарантированная константность позволяет использовать хеш строки в качестве части ключа.
Для этого не обязательно вообще все строки принудительно делать константными.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Забанили по IP, значит пора закрыть эту страницу.
Всем пока
Здравствуйте, Sinclair, Вы писали:
S>В С++ по давней традиции, смешивают две эти сущности в одну. Итоговый результат одинаково плохо выполняет обе задачи.
Мы сейчас сравниваем вшитую в язык имплементацию, от которой в общем то никуда не деться и дефолтную библиотечную имплементацию, которой никто не заставляет пользоваться.
Какой в этом вообще смысл?
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Забанили по IP, значит пора закрыть эту страницу.
Всем пока