Как стать автором
Обновить

Комментарии 148

Спасибо. Давай, шутки ради, докинем ссылки на книжки дохлого страуса и кернигана/ричи, чтобы вспомнить, как все начиналось с жуткого объявления аргументов:
main(argc, argv)
int argc;
char *argv[];
{
Вы принципиальный сторонник "прогресса"?
нет, мне просто как сейчас больше нравится :)
Ну я не знаю, сейчас работаю в Корее, так тут C/C++ очень любят и уважают. Java и иже с ними считаются более развлечениями, типа хобби (мне поясняли, что это секретарские языки, мол сидит девушка на работе, скучает и от нечего делать изучает яву, ваяет сайтик на коленке). Так что когда вижу дискуссии, что мол наступает новая эра, будущее за [подставить название] меня аж сомнения берут, а тем ли я занимаюсь... С другой стороны возьмите 1С, не язык, а приблуда, ан вон сколько народу кормит :)
ну...да...и...?
я про то, что сейчас си стал гораздо круче, чем был
не знаю, те времена не застал... я думал вы в общем к С с таким неуважением относитесь :)
аа:) не, я, наверное, просто плохо сфорулировал)
Другие языки, такие как C#, позволяют одному конструктору класса вызвать другой.


Неправда.
Ошибаетесь вы. Покурите Рихтера или спецификацию C#.
Спасибо, не курю.

namespace ConsoleApplication2
{
class Class1
{
private int foo;

public Class1()
{
Class1(1); // Class name not valid at this point
}

public Class1(int f)
{
foo = f;
}
}
}
Всё-таки, придётся покурить:

public Class1() : this(1)
{
// blah-blah-blah
}
Чьорт... Не успел я :)
Спасибо, буду знать.
namespace ConsoleApplication2
{
class Class1
{
private int foo;

public Class1(int f)
{
foo = f;
}

public Class1() : this(1)
{
}

}
}
И вам спасибо.
поржал когда зашел к вам в профиль и увидел "О себе: С# разработчик". это пипец, правда.
Что интересно отметить, грядущая версия языка C# будет реализовывать аналогичное поведение с помощью ключевого слова var.

Слово «грядущая» можно убрать — C# 3.0 давно вышел.

От перегрузки оператора «точка» отказались, по крайней мере в черновике 2007 года явно указано (13.5/3), что операторы . .* :: ?: перегружать нельзя.

Вообще, материал производит впечатление достаточно старого и эклектичного. Если кого-то всерьёз интересует C++09, лучше перепроверить по первоисточнику. Тем не менее, спасибо за заметку.
Ну я надеюсь, что это не последний мой материал из этой же серии: решил начать издалека. Тем более, если всё заготовленное в одну статью включить, то она получится слишком уж большой.
Спасибо за статью.

Пожалуйста, добавьте, что Microsoft выпустили Visual C++ 2008 Feature Pack, который реализует TR1.
Добавил, спасибо!
И который, кстати, включен в VS2008 sp1 beta (но не для express).
НЛО прилетело и опубликовало эту надпись здесь
Что вы говорите?! Попробуйте-ка построить высокопроизводительное приложение на Java! А потом сравните производительность! Перед этими языками просто разные задачи стоят!
не надо кормить троллей - тупо минусуйте ©
НЛО прилетело и опубликовало эту надпись здесь
зато на java написана цитирую "high scalability, high availability enterprise production platform" (c) посмотреть профиль bobuk радио-т-84
Бывает проще написать JavaEE приложение и отмасштабировать его по куче машин, которых можно накупить сколько угодно, чем писать программу на С++. Java очень хорош тем, что позволяет сэкономить на труде, заплатив побольше за аппаратуру. А в развитых странах работа программистов стоит больше, чем лишний писюк.

Хотя всё, конечно, от задачи зависит.
Есть пара НО.
1. У меня сосед на работе вечно матерится - "чо за фигня, как не возьмешь Java-софтину, так каждая тянет с собой свою версию JRE". Накопилось у него их предостаточно - вот тебе и кросплатформенность.
2. "Java очень хорош тем, что позволяет сэкономить на труде, заплатив побольше за аппаратуру." Это не плюс. Это означает что среда позволяет писать говено и перекладывать с больной головы на здоровую. Тем более такой финт ушами возможен только в одном случае - когда программа пишется на заказ и заказчик более не передает ее никому.
Вообщем предлагаю завязать с Java и прочими шарпами.

Что касается сабжа - интересна секция про потоки... Правда как-то все куце выглядит... Синхронизаций мало, active - это OpenMP фактически (дубляж?)
Что касается сабжа - интересна секция про потоки... Правда как-то все куце выглядит... Синхронизаций мало, active - это OpenMP фактически (дубляж?)
Да, мне тоже как-то странным показалось это. и так большинство компиляторов поддерживают OpenMP, зачем же такой огород городить? Уж лучше или переводить все прагмы из него в язык, либо оставить всё как есть, собственно не думаю, что разработка чего-то параллельного таким вот образом пострадает.
1. Странные вещи вы говорите. Сколько у вас там версий JRE? Их всего-то немного, к тому же можно поставить самую последнюю и забыть о предыдующих. А крупные корпоративные приложения вообще пишутся на заказ, т.е. окружение подстраивается под программу, а не наоборот.
2. "среда позволяет писать говено". Я только что говорил о Java, а вы? Джава не позволяет писать "говно", просто она выполняется несколько медленнее. Взамен она предлагает огромные возможности по масштабированию и увеличивает надежность (например сборщиком мусора). Критические части могут быть написаны на другом языке, если очень хочется. А вот разницы по работе GUI, к примеру вы не заметите: в этом случае С++ явно излишен.

"Вообщем предлагаю завязать с Java и прочими шарпами." - по какой причине? Предложения завязать с С++, Java, .NET или другим языком/платформой - это юношеский максимализм чистой воды. Скажите, каков ваш опыт написания серьёзных программ Enterprise уровня?
"Вообщем предлагаю завязать с Java и прочими шарпами." - по какой причине? "
По той простой причине, что культурные люди стараются оффтопить поменьше, и меряться "опытОМ написания серьёзных программ Enterprise уровня" и прочими пиписьками в других местах за кружечкой пива.
По-моему, опытный человек никогда не станет писать "Java - говно". Вы, конечно, можете остаться при своем мнении.
Вы перечитайте мой комментарий и вы увидите что там написано не "Java - говно", а Java позволяет писать говено, перекладывая криворукость программеров на плечи обслуживающего инфраструктуру персонала.
"Говено" можно написать на любом языке. Я вообще не вижу корреляции синтаксиса языка и качества кода. Квалифицированный программист будет писать одинаково хорошие программы, что на С++, что на Java. Справедливо и обратное: наймите школьника в серьёзный проект и в 99% случаев он напишет нечитаемую и нерасширяемую фигню.
Хорошо, тогда объясните мне - почему это выставляется как нее..кий плюс этого инструмента? Цитата:
"Java очень хорош тем, что позволяет сэкономить на труде, заплатив побольше за аппаратуру".
Плюс в том, что на Java быстро можно несколько быстрее писать приложения некоторого рода, а не то, что не нем можно писать "говно".
Согласен, но это несколько отличается от того, с чем я был не согласен ИЗНАЧАЛЬНО. А не согласен я был с тем, что а) экономия только в софте под заказ; б) экономия выглядит изначально сомнительной, как топорная сборка машины.
Видел я как-то обслуживающий персонал, который даже не знал где у него на сервере Tomcat. Казалось бы, причем тут Java?
НЛО прилетело и опубликовало эту надпись здесь
Отличная статья! Похоже своя и не перевод и это еще круче.
По теме: большая часть изменений очень отдаленно, но все таки напоминают в той или иной мене о C#. Быть может, скоро можно будет хоть часть работы для веба писать на C++.
Быть может, скоро можно будет хоть часть работы для веба писать на C++.

Что мешает сейчас, если уж так хочется, и какие перечисленные нововведения в этом престранном занятии помогут?
Присоединяюсь, что сейчас мешает?
regexp, foreach могут подсобить значительно.
Расширение списка перегружаемых операторов тоже очень кстати уже хотя бы для самописного строкового класса, если уж не озаботятся строками как обычно.
Regexp (под linux по крайней мере) и так уже есть давно, а обойтись без foreach и того проще.
насколько я знаю, pcre есть давно уже библиотека, да и в boost что-то такое есть, если мне не изменяет память.
Для регексов библиотек навалом (например, Boost.Regex).
А итератор реализовать - уж проще некуда, можно даже от них отказаца.
Я мог бы указать источники, но их довольно много пришлось анализировать, изучать. И то, немного запоздал с публикацией. Рад, что понравилось.

Да, я, кстати, тоже заметил приближение к C#.

Если смотреть со стороны программирования для Web, то для двусторонних сервисов (с бэкендом и фронтэндом) можно уже сейчас использовать «the powers of C++» для реализации «заширменной» части проектов (с новыми обновлениями это становится ещё удобнее, как мне кажется), а фронтэнд имплементировать через обычные повседневные вещи (Ruby, PHP, Python, и др.).

Быть может, скоро можно будет хоть часть работы для веба писать на C++.


Не надо. Не стоит, право, как истинный (истовый) сиплюсплюсник говорю вам - для всех задач - свои средства. А то у нас тут один «гений» (во всех фирмах есть такие чокнутые гики) написал XML-RPC сервер на чистом С++, с обработкой HTTP запросов и всем прочим....
Да в общем-то я тоже придерживаюсь такого мнения. Но был бы совсем не против, если бы в студии была возможность логично интегрировать в проект веб-сайта managed c++ код скажем для обработки какого-то массива данных. Именно код, а не подключить сборку из другого проекта или вовсе импортировать dll.
ну у нас для такого часто (хотя и не всегда) используется либо JNI, либо модули апача.
Так а что например мешает повесить приложение как FastCGI, а как сервер использовать тот же lighttpd?

Естественно, речь идет о крупных проектах...
XML-RPC сервер на чистом С++, с обработкой HTTP запросов и всем прочим
А почему бы и нет? Другое дело что NIH - опасный синдром, лучше всего использовать готовые библиотеки, благо их найти несложно...
Спасибо, полезная статья!
НЛО прилетело и опубликовало эту надпись здесь
и хорошо, что не добавили, а то одной вкусняшкой в с++ стало бы меньше
НЛО прилетело и опубликовало эту надпись здесь
нет-нет, этого и не нужно. смарт-поинтеры выполняют свою работу, остальное забота программиста, следить за своей памятью.
НЛО прилетело и опубликовало эту надпись здесь
мммм, я так понимаю, что одна из концепций С++ - это скорость. И я думаю, что именно поэтому С/С++ не перегружен всеми теми наворотами, присущим свежим языкам. Имхо, для работы с С/С++ нужно несколько больше думать и помнить о том, что ты делаешь, получая в результате эффективный код.
Если же добавить все фичи, за которые некоторые так ратуют, мы получим очередной шарп или яву с немного другим синтаксисом, и я не думаю, что это нужно. Тем более, что реализация сборки мусора без платформы (например, VM), на уровне рантайм библиотеки, окажется слишком сложной, даже если она будет опциональной.
НЛО прилетело и опубликовало эту надпись здесь
это так :) но я хотел сказать несколько другое. С++ сейчас почти мета-язык, который дает много низкоуровневых инструментов и, что хорошо, не собирается перебираться уровнем выше. Я так думаю, что D не наберет таких оборотов, как С++, хотя бы потому, что если он выйдет выше, в нишу шарпов/явы, то там ему не будет места, а если останется на низком уровне, рядом с С/С++, то, имхо, проиграет в производительности. Кроме того, врядли D займет место С/С++ в нише системного софта, игр или ОС.
В целом, это довольно интересная тема, но я рад, что концепт С++ развивается именно на своем месте, не пытаясь стать подобием более высоко-уровневых языков, которые, кстати, в свое время унаследовались именно от С++ :)
НЛО прилетело и опубликовало эту надпись здесь
Да ну, очередное выпячивание. Не учитывается ни контекст ни время создания языка ни его история.
Кстати, когда увидел урл было подумал, что речь пойдет про C--, эдакий эксперимент десятилетней и более давности. Тогда был предложен язык по синтаксису сильно напоминающий С, но смещенный в сторону ассемблера. Тогда такой язык расценивался как вполне жизнеспособный, код на асме еще массово писали. Теперь, наверное, идеи C-- автору статьи, которую вы приводите, вообще покажутся анахронизмом.
ну, зачем вы так про асм. Демосцена еще (пока) жива.
И то местами пишется на С++ и упаковывается UPX.
Да и не завидная участь у ассемблера - стать частью искусства.
Ну, не скажите. Без знания ассемблера абсолютно нечего делать в, скажем, геймдеве. И это не единственная такая область.
И, кстати, демок именно на С++, а не С, я не встречал.
мда, написано новичком в с++, да и вообще...
кстати, понятие "объектно-ориентированный" и "объектный" - разные вещи, так вот С++ - первое, а ява и смолтолк - второе. А ставить вопрос "язык должен быть ОО" - так он и так ОО, в чем проблема?
дальше не читал ибо бред
А я остановился на этой строчке:

…то скрыто от Вас будет создан объект класса std::string (а Вы знаете что в английском языке сокращение STD расшифровывается как Sexually Transmitted Deseases, т.е. заболевания, передающиеся половым путем), он передается…
Я тоже после пары подобных выпадов чуть не бросил читать, но дочитав до конца понял что возразить тут особо не получится: родовые болячки C++ показаны точно. И я действительно не видел ни одного крупного проекта где бы не было каких-либо доморощенных средств передачи метаинформации (будь то IDL, макросы, moc или что-либо ещё). И действительно многие вещи, которые в нормальном OOP делаются легко в C++ делаются путём кучи ухищрений. И rtti с exception'ами таки вносят вклад даже если их не использовать. А метапрограммирование на шаблонах убого. Но это как PL/1 - написано настолько много всего, что со всем этим кошмаром придётся жить ещё очень и очень долго. Ибо есть вещи, где реальной альтернативы нет или она ничуть не лучше C++ (содание программы на OCaml или Haskell, которая уже создаёт "реальную" программу на C я не могу признать более изящным решением, чем использование C++), а кроме того есть куча рекламы и банальная инерция...
мда, написано новичком в с++, да и вообще...
Ну насчёт новичка - вы явно не туда смотрели: если 15 лет опыта - это "новичковое" состояние, то нормальные гуру бывают только в языках типа COBOL или FORTRAN.

кстати, понятие "объектно-ориентированный" и "объектный"
И в чём разница? В том, что объектно-ориентированный язык не содержит нормальных объектных средств, а содержит слабую пародию существующую только на этапе компиляции? ООП в том виде, в каком он реализован в C++ не работает - иначе бы его не обвешивали кучей костылей все кто реально пытается его использовать.

А ставить вопрос "язык должен быть ОО" - так он и так ОО, в чем проблема?
Контрольный вопрос: в с нормальными объектными языками работали? Пусть даже Java (хотя это не лучший пример). Хотя бы Python, Ruby (про Common Lisp или Smalltalk я молчу). Если работали - то меня удивляет как вы могли не придти к тому же выводу, что и автор, если не работали - попробуйте и давайте обсудим C++ после этого. C++ - это плохая пародия на нормальную объектность, но в силу ряда причин он завоевал широкую популярность и, видимо, теперь уже не умрёт (как не умрут те же COBOL и FORTRAN). Удовольствия написание на нём кода не приносит - хотя по разным причинам делать этого приходится частенько. Проблема в том, что многие вещи, которые нормальные объектные языки предоставляют программисту в C++ приходится либо реализовывать с помощью тех или иных хаков, либо с помощью средств внешних по отношению к языку.
я могу ответить двояко: либо скромно промолчать, либо "напильники серые, потому что летят на север".

P.S. Особенно порадовала фраза: "ООП в том виде, в каком он реализован в C++ не работает".
Просто чудо, как фраза хороша. В таком случае такие отцы, как Гради Буч, например, скромно пялятся в пол, палят тоннами свои книги и идут в лес пасти баранов.
да, и кто вам сказал, что фраза "15 лет" - адекватна? я тоже могу 10 лет пялиться на обложку книги и потом заявлять, что я гуру.
просто рвёт в клочья от такой глупости, вы уж простите
называть С++ объектным, потом сравнивать его с чисто объектными языками, потом говорить, что язык ущербный, а потом еще питон и руби сюда плести. Это нечто.
Если вам так противно - пишите на объектных языках, но не стоит лезть в демагогию о С++ настолько мало зная в этой области.
просто рвёт в клочья от такой глупости, вы уж простите
Да уж прощаю. Я-то наивно полагал, что сравнивать можно любые языки между собой - ибо они имеют разные плюсы и минусы. То есть я не понимаю почему я не могу сравнить, скажем, Prolog и JavaScript. Ну да - это языки из разных областей. Ну и что? Любую задачу можно решить на любом языке - вопрос в том как.

Соответственно мне действительно неясно почему я не могу сравнивать C++ с питоном и руби. Из моей практики я вижу, что задачи, которые возникают сплошь и рядом (делегация, сериализация, etc) на C++ либо делаются отвратительно, либо не делаются никак (приходится привлекать кучу внеязыковых инструментов). Почему я не должен это относить к недостаткам языка только лишь на основании того, что он, прости госсподи, "объектно-ориентированный", а не "объектный"? Проблемы возникают независимо от ваших идиотских слассификаций...

А насчёт "знаний в этой области" - не знаю уж с чего вы решили, что у меня (или у автора обсудаемой статьи) этих знаний нет. Ответьте, например, на вопрос: какую проблему решает возможность опрделения в классе функции не принадлежащей классу (вы знаете как это делать, да) ? И после этого ответьте: почему нельзя было это сделать каким-нибудь более вменяемым способом ?
Я-то наивно полагал, что сравнивать можно любые языки между собой - ибо они имеют разные плюсы и минусы.
...
Соответственно мне действительно неясно почему я не могу сравнивать C++ с питоном и руби

а никто и не говорит, что нельзя
сравните асфальтовый каток и яхту, это будет типичным примером вашей речи :) Я тоже наивно полагал, что можно сравнить молоток и дрель, но почему то в реальной жизни как-то не прикладывается такое сравнение.
На вопросы я отвечать не буду, я уже говорил ниже. Я не задавал никаких вопросов, и отвечать так же не собираюсь. Хотите холивар - давайте тему соответствующую создавайте, там пообсуждаем.
В целом ваша речь выглядит так: "Типично я использую свойство клея "клеить" и мне оно очень нравится, но у молотка это свойство реализовано как-то не так, да еще и названо по другому - "прибивать"! Мне это не нравится абсолютно, потому как свойство "клеить" у молотка не работает так, как оно реализовано в молотке! И мне пофигу на ваши идиотские классификации!"
я тоже могу 10 лет пялиться на обложку книги и потом заявлять, что я гуру.
Собственно вы это и делаете, как я понял. Кроме заявлений о своей гигапуперкрутизне и отсылок "к крутым дядям" от вас пока ничего добиться не удалось.
а что вы ждете? холивара на тему С++ vs others? зря ждете. Не нравится С++ - никто вас не заставляет, пишите хоть на PL/1. Но в теме об эволюции С++ не стоит писать о том, что, видите ли, в С++ "как-то не так сделано ООП", мало того в вашем понимании.
Вон ниже точно сказано про такой тип людей: "don't get C++"
Почему в теме о C++ нельзя обсуждать реализацию вещей, которые C++ обещал людям дать, но не дал? Почему новые ревизии C++ не предлагают решение реально возникающих у людей проблем (та же сериализация объектов или интроспекция - не далее как сегодня полдня убили на решение проблемы, которая в любом нормальном объектном языке решается в две строки), а вместо этого обсуждаются какие-то "бантики сбоку" (о - теперь нам дадут возможность перекрывать operator. и мы сможем сделать не только smart pointers, но и smart references - какое счастье, 10 лет ждали) ?

Только лишь потому что C++ - такой, какой есть и кардинально изменить его уже нельзя? Exceptions значит добавить можно (это - типа не кардинальное изменение), а reflection - ни-ни. С чего вдруг?
вобщем, я понял, что С++ вам поперек горла :)
Если изменить С++ лично для вас - будет C#
Вы этого хотите? Дык почему бы не взять C# и забыть о С++?

P.S. Опять же вы говорили о своем опыте выше, но не понимать проблем введения reflection, уж извините еще раз :) Возможно, вам стоит написать еще одну статейку, как автор выше, запостить ее сюда и выслушать коментарии. Хотя в вашем случае вообще не ясно зачем вам С++, если он вам так не нравится. Бросьте эту каку и пишите на шарпе, делов то.
НЛО прилетело и опубликовало эту надпись здесь
Reflection добавить нельзя, хотя всем очень очень хочется %), потому наличия reflection и является один из значительных плюсов явы, шарпов, питонов в плане языковой гибкости. Однако в этих языках reflection идет не бесплатно.
Есть люди, которые просто don't get C и C++. Ничего в этом плохого нет. Просто не нужно таким людям писать статьи.

Да, C++ не идеален. Однако это не мешает быть ему эффективным инструментом в умелых руках.
Однако это не мешает быть ему эффективным инструментом в умелых руках.
Мешает. В большинстве случаев попытки сделать что-то на плюсах порождают кучу новых инструментов, которые по хорошему дорлжны быть встроены в язык. Получаются такие мини-вселенные в разных библиотеках, которые при попытке их объединить в одной программе рождают мегабайты кода. Работает ли всё это? Да - работает, но это - не более, чем подтверждение RFC 1925 в приложении к языкам программирования...
Ещё неплохо бы помнить о том, что инструмент может быть эффективным, если он выбирается под задачу. Я бы не рискнул садиться писать веб-сервис на C++, но и движок игры, где нужно выжать максимум fps, я бы не стал писать на Питоне.
Обсуждать там нечего: "Книгой самого Страуструпа вообще убить можно. (А вот прочитать до конца практически нельзя)". Всё-таки, неплохо бы дочитать Страуструпа, прежде чем бросаться на амбразуру с подобными статьями.
Проблема этой статьи в том, что в ней в одну кучу свалены справедливые выпады в сторону далеко не идеального языка и откровенно страные умозаключения.
Разумеется, у С++ есть огромное количество кривостей, неудобств и проблем, но ведь наши недостатки являются продолжениями наших достоинств? Как сказал кто-то, довольно трудно иметь красивую и скромную жену одновременно.
Тот же Страуструп по поводу простоты Джавы говорил: "подождём хотя бы несколько лет и посмотрим, останется ли Джава такой же простой".
Как мы видим, Сишарп сильно расширился к третьей версии. Мой когда-то любимый язык Бейсик на ZX Spectrum был простым, по сравнению с ним QuickBasic показался мне жутким монстром в своё время. Простота любого языка обязательно вылезает боком в другом месте. На эту тему высказывался и Спольски: http://www.joelonsoftware.com/articles/f… Не верю я в бесплатную простоту.

В качестве примера явно предвзятого суждения можно указать на оценку автором библиотеки STL. Только начиная её изучать, я ради интереса написал программу, подсчитывающую частоту встречаемости разных слов во входном тексте. Результаты нужно было печатать с использованием различных критериев сортировки: по алфавиту, по частоте.

Тогда мне показалось (и сейчас кажется), что делается это в STL довольно просто и эффективно. Ничуть не сложнее, чем в той же Джаве.

А всякие разговоры на тему reference semantics vs. value semantics и т.п. — это чистой воды вкусовщина. В Джаве новички тоже пишут string a, b; ... if(a == b) вместо a.equals(b). И что теперь?..
ничего не понял, потому плюс в топик и карму :)
Какого года это текст?
> Комитет по разработке стандартов планирует завершить C++09 к концу 2007 года.
Это же исторический раздел, то есть псевдонастоящее время.
По крайней мере, задумывался этот блок текста как некий «флешбек».
Ага...
Мало акцентируется на том что это "флешбек".
Можно было бы немного аналитики со стороны сегодняшенго времени добавить.
НЛО прилетело и опубликовало эту надпись здесь
возможно, стоило промолчать?
Почему же, самокритичность это хорошо, человек хотя бы признаёт что он некомпетентен.
НЛО прилетело и опубликовало эту надпись здесь
А вы чётче формулируете, а то понять можно по-разному.
Но почему-то огромное число людей понимают, а вы не понимаете.
"я вообще не понимаю" - вы не понимаете, кто-то другой понимает, значит он компетентнее, разве не так? :)
НЛО прилетело и опубликовало эту надпись здесь
А что Всас мешает писать на C++? Если можно, то поподробнее.
*Вам
пишут пишут много и эффективно. И на плюсах и на голом си. И смысл в этом есть иногда. Чтож.. очень жаль что вы не понимаете как на плюсах можно писать =).
Мне кажется, что это неверный путь развития C++. Он хорош тем, что в нём мало возможностей.
Скорее не "мало возможностей", а "мало средств".
В какой-то степени согласен, обилие ключевых слов в языке меня всегда наводит на мысли об отсутствии основопологающей концепции в языке. А может быть, и действително нет простых способов борьбы с энтропией битов. :)
НЛО прилетело и опубликовало эту надпись здесь
Более того, ошибкой! Эти усложнения только ухудшат язык.
НЛО прилетело и опубликовало эту надпись здесь
Хорошая статья. Правильная. Редкость для Хабра, задвинутого на ущербном PHP.
А по сути - по сути, если бы бабушка имела член, то она бы уже была дедушкой. С появлением Java и С# это всё выглядит как агония. Смысл С++ в том и стоит, что улучшить его сложно. Его миссия в эффективности. Правильно комитет сказал - производительность наше всё! Если его расширить за счёт удобства и безопастности, то производительность упадёт и это будет другой, тож отличнейшиё язык, называемый в быту Джавой!
нет, вы не правы. многие изменения очень логичны (например использование ключевого слова "auto" - аналог c# var), другие приятны - decltype,
третьи... удивительно что их давно не ввели в стандарт (я насчет >> в шаблонах)
единственное что может отразиться на производительности - atomic, thread, etc: эти нововведения целиком на совести разработчиков компиляторов

очень приятно что любимый язык развивается, и как раз в тех направлениях о которых я думал последнее время. еще интереснее будет если добавят честные typedef:

typedef unsigned int samplenum_t;

int i = 10;
samlenum_t current(0);
++current;
current = i; // error: different types
Вместо синонима вы получите новый тип, со всеми вытекающими. Нужно ли это? :-)
конечно! представьте:

typedef unsigned int video_stream_index_t;
typedef unsigned int frame_num_t;

video_stream_index_t v=0;
frame_num_t frame=1;

frame = v; // compiler error: different types!

и ведь здесь мы можем различить типы не по размеру там данных, а по тому значению которые они в себе несут в программе!
ммм, это чудно, но тогда эти типы ничем не отличаются от классов, для них нужно вводить поддержку, проверки и все остальное. typedef не вводит новый тип, отсюда его поведение.
Получается, что наоборот я тоже не смогу сделать.
std::string err[] = { "No Error", "Error One", "Error Two" };
typedef unsigned int error_index_t;
//...
error_index_t i = ...;
err[i]; // в вашем случае должна быть ошибка, я так понимаю :)
слишком это заденет существующий код и изменит поведение typedef, который сейчас на уровне препроцессора работает.
да, это должно быть что-то типа класса, но такого, чтобы не было надобности переопределять операторы базового типа.

чтобы операторы остались теми же, но чтобы не было возможности присвоить переменную данного типа переменной базового и наоборот. сейчас typedef работает просто как alias, а хотелось бы чтобы он вводил новый тип, который имел бы свое место в системе типов.

т.е. мы говорим компилятору: вот новый тип, полностью аналогичный базовому, с теми же операциями. но пожалуйста, милый компилятор, не разрешай никому путать этот новый тип и базовый.

вот например представьте

typedef unsigned int column_index_t;
typedef unsigned int row_index_t;
column_index_t col=0;
row_index_t row=0;
++row;
++col;
row = col; // error!!!

это действительно ошибка! ведь хотя и базовые типы unsigned int, но в программе column_index_t и row_index_t выполняют совершенно различную роль и их нельзя смешивать!
вот именно :-) С++ налагает на программиста дополнительные обязанности, дабы не перегружать язык сомнительными идиомами. Ведь во главе угла - производительность. Вам ничего не стоит запомнить разницу, а вместо этого вы просите компилятор копировать типы. И если в случае с базовыми затраты минимальны, то представьте конструкции посложнее
typedef SomeFunc > NewType;
в этом случае копирование типов уже не так однозначно.
К тому же алиасы сделаны для удобства программиста и не предполагают никаких телодвижений от компилятора и это хорошо имхо :) Вместо 100 символов вы задаете алиас на 5-10, вы сами должны знать зачем вам алиас и откуда у него растут ноги, в этом суть.
Представьте ситуацию, когда у вас коллекция возвращает кол-во типа size_t, а функция чтения чего-либо - int, и вы просто не сможете сравнить или использовать эти кол-ва, потому как это разные типы.
Storage s(...);
std::vector vec;
vec.reserve(s.size());
Причем, если возвращаемый тип s.size() != vector::size_type, то у вас ничего не получится, будет лишний геморой с кастом, а в результате получите каст size_t к size_t, хотя и с разными названиями.
Собсно у нас, наверное, разные взгляды. Я считаю, что С++ должен оставаться именно низкоуровневым, где программист сам решает, что делать. А решения копилятора следует оставить другим языкам. В этом и кайф С++, если я точно знаю, что делаю, то получаю конфетку, в противном случае - бяку и сам в этом виноват, потому что должен знать.
хотел написать в первом примере
typedef SomeFunc<Policy, Behaviour<Sample> > NewType;
не думаю, что наличие такого тайпдефа ударит по производительности. Это ведь всё проверки времени компиляции, а не времени выполнения.
Если на то пошло, зачем тогда вообще тайпдеф? Пишите int и не заморачивайтесь.
да, вы правы, абсолютно не ударит.
то что я предлагаю, чтобы для типов, разных по СМЫСЛУ, но одинаковых по бинарной природе, компилятор генерировал ошибки или по крайней мере предупреждения, (конечно же, у вас стоит максимальный warning level и включена опция treat warnings as errors?)
> конечно же, у вас стоит максимальный warning level и
> включена опция treat warnings as errors?)
Ну зачем же меня так прилюдно стыдить? :) Каюсь, иногда дьявол сбивает с пути истинного!
почему нельзя? очень часто надо высчитывать значение строки от значения столбца, а в вашем примере это приведет к хрен знает чему. и что, column_index_t - теперь не ансигнед? его нельзя складыват с ансигнедами?

глупость вы предлагаете с тайпдефом - он и предназначен для синонимизации, а для того, что вы говорите - есть другие методы. а прелесть си как раз в нестрогой типизации.
нет, не глупость!

typedef это TYPE DEFINITION - определение типа!
в с++ неправильный typedef. он не является определением типа, а является просто синонимом для базового типа. если бы мне хотелось иметь синоним, я бы просто юзал #define или ввели бы ключевое слово alias для синонимов.

если прелесть с++ в нестрогой типизации, то нафига там вообще типы, классы, структуры, касты? может обошлись бы байтами и массивами байтов, а?

да, в шаблонах можно выразить то о чем я говорю, достаточно переопределить у шаблона все операторы базового типа! но это гемморойно, мне всего лишь нужно предупреждение от компилятора, что типы различны по смыслу. зачем мне вот этот велосипед
http://www.synesis.com.au/software/stlsoft/doc-1.9/classstlsoft_1_1true__typedef.html
интересная статейка Спольски про венгерскую нотацию:
"http://local.joelonsoftware.com/mediawiki/index.php/Как заставить неправильный код выглядеть неправильно"

изначально в майкрософт при создании Экселя венгерская нотация была использована для обозначения СМЫСЛОВЫХ типов переменных:
int colA, colB, colC;
int raw1, raw2, raw3;
таким образом, когда программист видел присваивание
colA = raw1
у него должна была срабатывать внутренняя сигнализация, что так присваивать нельзя, потому что по разные стороны от знака присваивания стоят разные по смыслу типы

то, о чем я говорю - чтобы переместить эту "сигнализацию" на плечи компайлера
Что поделаешь - C++ придуман как расширение C и сначала вообще был реализован через специальный препроцессор (C++ транслировался в C). А при программировании на "C" "мягкая" типизация для целочисленных типов всегда считалась важной для эффективности кода и для компактности записи программы.
Подход, при котором typedef определяет принципиально новый тип данных (в том числе для целых чисел), действительно позволяет избежать каких-то ошибок, но на практике ведет к раздутию текста программы из-за явных приведений типов.
Вот видел я библиотеку математических подпрограмм на языке Ада, написанных в таком стиле, как Вы предлагаете - с введением отдельных типов под каждый индекс массива. И что? Так как в реальной жизни во многих процедурах приходится использовать одну и туже переменную как для строчного, так и для столбцового индекса, то читабельное A(I, I) превращается в A(I, column_type(I)) - и тексты пестрят этими явными приведениями в длинных выражениях, что очень портит внешний вид программы, снижает ее читабельность. А идея-то была хорошая...
Так что в принципе было бы хорошо иметь возможность ввести свои настоящие типы конструкцией а-ля typedef, но совместимость с "C" и стремление в последнем к эффективному коду и читабельности простой программы привело к тому, что typedef вводит по сути синоним, а не новый тип для целых.
Согласен по поводу тайпдефа. Но ведь совершенно ясно, что семантику старого не изменят (ради совместимости), а новое ключевое слово вводить поленятся... Я вот не знаю, есть ли в Бусте такой "честный" тайпдеф на шаблонах? Ведь по сути то, что Вы предлагаете, можно сделать иным способом — через пустой параметризированный класс?
Мысли вслух:
1) Было бы классно, если бы конструкторы родительских классов можно было бы вызывать не только из строки инициализации, а и из произвольного места в теле конструктора наследуемого класса. Как в Java (насколько я знаю).
2) nullptr - имхо лучше бы сделали название просто «null» :) Меньше букв писать, да и красивее.

А вообще классно. Впечатляет.


>> Одной из мощнейщих возможностей C++ была передача параметров по ссылке (by reference) с использованием оператора «&». Это позволяло модифицировать данные параметра напрямую, без использования указателей.

На самом деле ссылки представляют собой точно тоже самое, что и указатели, с той лишь разницей, что компилятор накладывает определённые ограничения на их использование. А внутри это те же самые указатели :)
Ссылка - это стек. Если вы получили ссылку, то уже уверены, что это "рабочий" объект, а не NULL, либо непонятно что, ведь можно путем диких кастов передать валидный указатель, но объект будет нерабочий :) Кроме того, вы не беспокоитесь на счет памяти, как в случае с указателями.
Не всегда. Я встречал такой код:

void fn(Class & ref = * ((Class*)NULL) ) {
if( &ref != NULL) {
//...
}
}

Да-да, я в курсе, что за такое надо отрывать руки, и любой компилятор имеет полное право послать этот код лесом. Но в MSVC работало.
мысль: из любого места конструктора наследуемого класса вызывать конструктор базового, имхо, не есть "гут" т.к. будет не очевидна инициализация элементов базового класса. если же конструктор явно прописан сразу в строке инициализации - это более наглядно.
если на это не обращать внимания то прикрутить такую "фишечку" реально - при срабатывании конструктора производного, выделение памяти для базового уже произошло по сути.
хм ... доп нагрузка на рантайм будет - если конструктор производного не вызвал явно конструктор базового, то "кто-то" ведь должен вызвать конструктор базового?
>> мысль: из любого места конструктора наследуемого класса вызывать конструктор базового, имхо, не есть "гут" т.к. будет не очевидна инициализация элементов базового класса. если же конструктор явно прописан сразу в строке инициализации - это более наглядно.

Наглядно - не глядно, а в некоторых случаях очень неудобно ;) Иногда вычисления аргументов для конструктора базового класса на основе аргументов производного могут быть нетривиальны. Вот тут как раз бы и пригодились обыкновенные инструкции - if'ы, арифметика, вызовы функций, etc. Но нет - мы скованы ограниченениями строки инициализации - в ней для инициализации подавай либо готовую переменную, либо результат функции. Здесь 2 выхода. Можно писать функцию-член класса для вычисления каждого параметра дял конструктора базового класса. Либо сделать в базовом классе конструктор по умолчанию без аргументов, и отдельную функцию-инициализатор, которую уже и вызывать в конструкторе производного. Я в таких случаях обычно пользуюсь последним подходом. Но имхо оба варианта какие-то кривые ;)

>> хм ... доп нагрузка на рантайм будет - если конструктор производного не вызвал явно конструктор базового, то "кто-то" ведь должен вызвать конструктор базового?
А тут всё просто - пусть компилятор выдает ошибку, если не нашёл явного вызова конструктора базового класса в коде конструктора производного (за исключением случая, когда у базового класса есть конструктор по умолчанию, разумеется).
насчет первого - согласен. и функция инициализатор, которую нужно еще делать protected, кривое решение.
насчет второго - компилятора мало будет. в рантайме нужно ловить был вызов базового или нет т.к., как ты и сам говоришь, код инициализации может быть нетривиальным иначе есть шанс что вызова не будет.
Вообще-то, базовые конструкторы в С++ всегда выполняются перед конструктором производного класса.
Вряд ли это поведение кто-нибудь будет менять, да и с чего бы.
По пункту 1)
Идея абсолютно не классная и никогда не будет реализована в хорошем языке. Понимаете - конструктор это метод конструирующий объект. Объекты создаются строго в порядке иерархии наследования. Каждый потомок в чём-то потенциально опирается на предка. Возможность вызывать конструктор в любой строке, по сути означает, что будет возможность выполнять некий код потомка до того, как сконструирован его предок. Грубо говоря, детёнок начинает говорить до того, как родилась его мама. :-)
В джава также нельзя этого делать. Там просто синтаксически вызов конструктора предка идёт в первой строке конструктора потомка. Строго в первой и нигде больше. Исключительно для того, что бы показать каким конкретно конструктором мы хотим создать предка. Никакую функцию в параметр также вставить нельзя. Компилятор выдаст ошибку.
а что лямбда-функции из c++0x выкинули чтоли?!
А они там были? Разве это всё не буст?..
(с другой стороны, какая разница — 0x или boost — есть буст, и радуемся... :)
нет не буст: ссылка на википедию
хабр не дал мне запостить ссылку через тег, http://en.wikipedia.org/wiki/C%2B%2B0x#Lambda_functions_and_expressions
Обсудили с коллегами статью. Возникли большие вопросы на тему реализации ключевого слова auto. Фактически, это отход от идеологии C++, потому что вам при применении этой конструкции никогда не удастся угадать, КАК оно сработало. При том, что для указанной в примере гибкой смены типа параметра функции вполне достаточно (и правильно) typedef на нужный тип, после чего проблема отваливается сама собой.

Более того, непонятно, как компилятор будет интерпретировать конструкцию auto в случае использования в правой части выражения какого-то хитрого объекта с множественным наследованием, изрядным количеством потомков и приведённого к своему текущему типу тоже от потомка :) В общем, ошибкоопасная бня :)

Насчёт rvalue тоже непонятно, зачем? Есть же shared_ptr, который даст в случае чего тот же результат. Зато синтаксис нереальный: &&value - это что такое? Ссылка на ссылку?

Впрочем, nullptr порадовал. Расширение stl тоже порадовало. Вызов конструкторов - "нунаконецто" :)
А функционала для работы с многопоточностью с нетерпением ждём всем отделом разработки :)
приведите пожалуйста пример, когда auto является ошибкоопасной бнёй
Пожалуйста. Есть SimpleClass, есть наследованный от него SuperClass. В них обоих есть метод do(), перегруженный в наследнике.

void x(SuperClass c) {
auto ptr = &c;
...
y(ptr); // будет ли ошибка?
}

void y(SimpleClass* c) {
c->do(); // чей метод вызовется?
}
> Насчёт rvalue тоже непонятно, зачем? Есть же shared_ptr, который даст в случае чего тот же результат.

Т.е. вы предлагаете вместо:

std::vector<int> gen() { ... }

std::vector<int> x = gen();

Писать:

boost::shared_ptr<std::vector<int> > gen() { ... }

boost::shared_ptr<std::vector<int> > x = gen();

?

Или так:

void gen(std::vector<int> & x) { ... }

std::vector<int> x;
gen(x);


Второй вариант бессмысленный, а третий используют сейчас. Но согласитесь, что первый выглядит куда лучше. Более того, если покапаться, можно найти другие примеры, где третий вариант не подойдёт (в каких-нибудь шаблонных ситуациях, когда различить, какой вариант сработает - сложно, или невозможно, или если нет конструктора по умолчанию и т.п.)
М-да. В школе никогда бы не написал "покапаться". Мне стыдно.
rvalue ссылки, по описаному выше, всеголишь метод передвигать данные из одной переменной в другую безовсяких копирований. А-ля "переименование" переменной.
Ну да, в принципе, их для таких ситуаций и придумали, хотя есть и другие случаи.
Но в любом случае, как Страуструп сам говорил (или не он?), что язык используют далеко не всегда так, как задумывал создатель. Мало ли, для чего их ещё могут применить, но даже такое знание, что объект временный и его можно убить - очень полезно, по-моему.
а что в этом плохого? :) именно на этом (делать не так как задумывали создатели) построен в частности буст :)
А я и не говорил, что это плохо. Наоборот, не в меньшей степени и по этой причине нужны улучшения. Мало ли чего ещё полезного придумают :)
Ну, лично я предпочитаю во всех случаях, когда нужно использовать конструкцию вроде std::vector более одного раза сразу делать:

typedef std::vector IntVector;

Далее, соответственно, спокойненько пишем:

IntVector gen() { ... }
IntVector x = gen();

При этом если из другого модуля использовать возвращаемое функцией gen() значение не как IntVector, а как std::vector , компилятор это прекрасно поймёт. Впрочем, это уже к rvalue не относится, насколько я понимаю :)

Что же касается shared_ptr, его вполне можно использовать в том же смысле, что и rvalue - избежание бессмысленного расхода памяти на копирование больших объектов. Тем более, что в C++09 предполагается использование его без boost, то есть в виде std::shared_ptr. Смысл тот же - пока мы работаем с данными не модифицируя их, мы работаем с переданным нам в качестве параметра экземпляром. Как только пытаемся модифицировать данные - автоматически вызывается конструктор копирования и мы получаем локальную модифицированную версию объекта. Звучит страшно, на практике очень удобно, называется explicit sharing. Впервые такой подход (правда, реализованный в самих объектах), увидел в Qt3, в объектах типа QValueList.

P.S. Прошу прощения, что код никак не выделен, не могу html использовать.
P.P.S. Или мы друг друга неправильно поняли?
Видимо не так поняли друг друга.
В вашем коде с IntVector будет копирование после возврата из функции gen().
Такие тривиальные случаи, в прицнипе, компилятор сможет оптимизировать, но не всегда.
В случае же с rvalue ссылкой мы точно знаем, что переданный объект - временный, его можно безболезненно менять и убивать. Т.е., вектор просто в этом конструкторе напишет:

vector(vector && other) { swap(other); }

Т.е. обойдёмся только заменой пары указателей, вместо копирования.
Сейчас приходится полагаться на компилятор, который должен догадаться, что переменная временная, что ей инициализуется объект и т.п., в сложных случаях он и этого не сможет, поэтому часто делают так, как я написал в предыдущем посте третьим куском кода.
Долго набирал комментарий, нажал "написать" и все пропало. :-( Текст восстановить нажатием Back не удается. Такое происходит уже не первый раз. Очень неприятно.

По теме: спасибо за статью!

От выделения из кучи не откажешься, но стратегия выделения может быть разной (например в C# макс. оптимизирован new).

Критические места в коде можно и без исключений с RTTI реализовать.

Вообще, развитие C++ приятно поразило: настолько все по делу! Удивительно это и радует, потому что некоторые вещи реально облегчат существование (например, auto и decltype).
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Истории