![]() |
Модераторы: Daevaorn |
![]() ![]() ![]() |
|
archimed7592 |
|
||||||||||||||||||||||||||||||||||||||||
![]() Архимед ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2531 Регистрация: 12.6.2004 Где: Moscow Репутация: 58 Всего: 93 |
К октябрю 2007 года комитет запланировал публикацию законченного черновика стандарта C++09(который будет доступен публике для рассмотрения и критики).
В октябре 2008 комитет внесёт окончательные коррективы в стандарт и, наконец, на 2009 год запланированна публикация нового стандарта "ISO/IEC 14883(2009): Programming Language C++". Надеюсь, не мне одному интересно, что же ожидает нас в новом С++. Потому, проштудировав документы, доступные обычным смертным на сайте open-std.org, я сделал маленький обзорчик ожидаемых вкусностей, которые готовит нам новый стандарт. Итак, в кратце, крупные нововведения следующие:
[hr] Rvalue References Появились т.н. ссылки на rvalue. Сначала поясню зачем их вообще изобрели. Исходных проблемы было две: forwarding problem и move semantics. Forwarding problem Эта проблема заключается в том, что текущий стандарт, для заданного выражения E(a1,a2,...,aN), которое зависит от параметров a1,a2,...,aN, не позволяет написать такую ф-цию(или функтор), которая будет эквивалентна этому выражению. Проблема актуальна для разного рода шаблонных обёрток, фабрик, обобщённых функторов и т.п. За идеал перенаправляющей ф-ции(perfect fowarding function) f(a1,a2,...,aN), которая вызывает g(a1,a2,...,aN) взяли следующие критерии:
Вот простейший пример:
Короче говоря, текущий стандарт решить эту проблему не позволяет. Move semantics С++ - язык, построенный на семантике копирования(copy semantics). Что такое семантика перемещения(move semantics)? Хороший пример - std::auto_ptr. Его конструктор копирования берёт неконстантную ссылку и перемещает хранимую в исходном объекте сущность в новый объект(тем самым избегая глубокого копирования). Но, несмотря на то, что конструктор копирования auto_ptr берёт неконстантную ссылку, его суть не в том, чтобы изменить объект, а в том, чтобы переместить к себе его содержимое. Так же, семантика перемещения не помешала бы строкам. Вообразим, что строки у нас без подсчёта ссылок. Теперь вообразим, сколько ресурсов будет затрачено на вычисление такого выражения:
будет создано как минимум 5 временных объектов и потом ещё произойдёт глубокое копирование результирующей строки в s(если нету подсчёта ссылок). А теперь, вообразим, как было бы прекрасно, если бы конструктор копирования умел бы отличать какой объект ему подсунули - временный или нет. Действительно, о временных объектах можно не волноваться и с чистой совестью "забирать" у них выделеный ими буфер, без необходимости глубокого копирования. К слову, эту проблему можно решить текущими возможностями языка, но очень уж некрасиво... Что же нам предлагает новый стандарт? А предлагает он следующее: ввести новый тип ссылок - rvalue reference. Синтаксис:
Любая именованная rvalue-ссылка трактуется как lvalue. Любая неименованная rvalue-ссылка трактуется как rvalue. Т.к. теперь появилась возможность различать тип выражения(lvalue или rvalue), появилась и возможность кастовать lvalue к rvalue: static_cast<T &&>(lval) будет трактоваться как rvalue. Возвращаемое значение из ф-ции интерпретируется как rvalue т. е.
Т.о. можно избежать глубокого копирования и ограничиться только лишь перемещением из возвращающей ф-ции в вызвавшую(при наличии соответствующего конструктора). Forwarding problem решается теперь следующим образом:
Move semantics обеспечивается следующим образом:
В случаях, когда необходимо вызвать конструктор перемещения для объекта, который не является rvalue, можно сделать каст, запросив необходимое поведение следующим образом:
Лично я эту фичу считаю очень полезной. Особенно, учитывая появившуюся возможность отличать временные объекты от невременных таким образом увеличив производительность в разы, избавившись от лишних операций копирования. Template aliases Думаю все оценят эту фичу. Проблем, побудивших ввести алиасы две. Первая заключается в том, что очень часто появляется нужда в "шаблонном typedef'е". Wrokaround'ом этой проблемы как правило является следующая конструкция:
Вторая же проблема выражается в том, что при использовании вышеобозначенного workaround'а перестаёт работать вывод шаблонных параметров.
Алиасы позволяют решить обе проблемы. Алиасы представляют из себя объявления. Они не определяют новых типов.
Шаблонные алиасы нельзя специализировать, но, можно специализировать тип синонимом которого является алиас. [hr] Variadic templates Это нововведение избавляет программиста, реализующего библиотеку списков типов или библиотеку, подобную boost::bind от реализации всех возможных вариаций типа
И позволяет сделать шаблон, принимающий переменное количество шаблонных параметров:
Как к типам(Args), так и к экземплярам этих типов(args) можно применять разные операторы.
Количество типов в наборе можно узнать с помощью нового оператора sizeof...:
Языковых средств для вытягивания типов из набора(Args) нету, но, это не очень сложно делается руками(и уже сделано в стандартной библиотеке - std::tuple и иже с ним). Языковых средств для вытягивания значения из набора(args) вроде как нету, но, опять же, руками это делается несложно - std::tuple тому пример. В документах встречалось упоминание, что значение можно вытянуть как из массива(args[3], к примеру), но в грамматике я такого упоминания не нашел. [hr] Concepts Ну это вообще просто сказка ![]() Пару слов про сами концепции. Любой, кто использовал обобщённые алгоритмы/структуры данных сталкивался с разного рода требованиями к обобщаемому типу. Наиболее распространенные: DefaultConstructible, CopyConstructible, LessThanComparable. Также, концепциями являются InputIterator, OutputIterator, ForwardIterator, etc. Короче говоря, это требования к обобщаемому типу, невыполнение которых может привести к ошибке инстанцирования шаблона. На данный момент такие требования повсеместно встречаются в документации(IS, boost docs, etc). Теперь эти требования можно будет выражать в коде. Какие проблемы решат концепции? Ну, во-первых, это, конечно то, что теперь, тип будет сначала проверятся на соответствие концепции и только после удачного завершения этой проверки, произойдёт попытка инстанцирования шаблона. Т.о. если тип не LessThanComparable, то при попытке использовать его в контейнере map(к примеру) не придётся втыкать на километры выданных компилятором ошибок. Ошибка будет выглядеть примерно так: "тип T не является LessThanComparable", что, замечу, большой плюс. Все, кто использовал boost::bind/lambda::bind оценят ![]() Во-вторых, для компилируемого на данный момент клиентского кода, увеличится устойчивость к будущим изменениям в коде библиотеки(гарантии на завтрашний день) - если требование раньше было всего лишь словами и только в следующей версии библиотеки эти слова воплотили в жизнь, то без концепций, некоторый клиентский код может перестать работать, чего не скажешь о коде защищенном концепциями - даже если шаблон мог бы быть инстанцирован, но тип не прошёл проверок на соответствие концепциям, то будет выдана ошибка. В-третьих, писать обобщённый код станет проще. С концепциями можно делать что только душе угодно. К примеру, если тип vector не соответствует концепции Stack(у него нету ф-ций push/pop), но, принципиально его можно использовать как тип соответствующий этой концепции(можно использовать ф-ции push_back/pop_back), то, без потери для общности, можно написать что-то вроде адаптера(concept_map), который будет приспосабливать данный тип к заданной концепции. Концепциями можно защитить не весь класс, а только некоторые его методы. Также, можно разработать несколько версий алгоритма эффективных для той или иной концепции и перегрузить его так, что будет выбран наиболее подходящий алгоритм. Синтаксис концепций интуитивно понятен и поясню я только некоторые моменты.
Ключевое слово where в последней версии вроде как решили заменить на слово requires. Unicode characters/strings Ну, собственно, ничего интересного, кроме самого факта: теперь в С++ оффициальная поддержка UTF-16(u"...") и UTF-32(U"..."). Ну а факт, я считаю, немаловажный и вполне достойный соответствующего внимания со стороны публики ![]() Появились новые типы char16_t и char32_t. Также, отдельно рассматривается добавление UTF-8(E"..."). [hr] Initializer lists
Достаточно обширное нововведение. Пока всех подробностей не выяснил, но, в двух словах постараюсь рассказать. В языках типа C# практикуется такое:[CODE=c#]f(new char[] {'1', 'a', '-'});[/CODE] В С++09 предполагается нечто подобное(только без new ![]() Теперь можно будет написать
Как написать класс, чтобы его можно было вот так инициализировать?
-------------------- If you have an apple and I have an apple and we exchange apples then you and I will still each have one apple. But if you have an idea and I have an idea and we exchange these ideas, then each of us will have two ideas. © George Bernard Shaw |
||||||||||||||||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||||||||||||||||
S.A.G. |
|
|||
![]() не эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1339 Регистрация: 20.7.2006 Где: in ad equate Репутация: нет Всего: 19 |
А разве Standard C++ так уж и везде реализован?
К 2009 опубликуют а кодить можно будет его применяя к 2010-2012 Это сообщение отредактировал(а) S.A.G. - 12.6.2007, 14:06 -------------------- Вот она задачка: спасти себя от себя самого © Cube Sometimes good people do evil things © A Simple Plan |
|||
|
||||
archimed7592 |
|
||||||||||||||||||||||||||||||||||||||||
![]() Архимед ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2531 Регистрация: 12.6.2004 Где: Moscow Репутация: 58 Всего: 93 |
Синтаксические мелочи
static_assert Новое ключевое слово, позволяет во время компиляции сделать проверку и, в случае чего, сгенерить ошибку компиляции(текст ошибки можно указывать). Наибольшее применение, имхо, будет иметь в шаблонах, хотя, с появлением концепций - сомнительно ![]() Так же, возможно использование как замена старой доброй директивы #error.
Расширенная функциональность sizeof
Delegating Constructors
Inheriting Constructors
Deducing the type of variable from its initializer expression. Достаточно интересная штука... настолько же, насколько и опасная, имхо...
Extended friend Declarations
Extern templates
сделано для того, чтобы диначическая библиотека могла сделать у себя explicit instantination, а клиент у себя extern explicit instantintaion Right Angle Brackets
Добавлено @ 14:09 Добавлено @ 14:11 Range-based for-loop
C99 Compatibility: __func__
Generalized Constant Expressions constexpr - новое ключевое слово. Суть нововведения в том, что теперь, например, можно как размерность массива использовать результат, возвращенный ф-цией.
Explicit Conversion Operators
Raw String Literals
A name for the null pointer: nullptr
Alignment Support
Prohibited access specifier
Explicit class and default definitions
Defaulted and Deleted Functions
Pure implementation method declaration
Strongly Typed Enums
Добавлено @ 14:14 Формальные мелочи Conditionally-Supported Behavior Добавлен новый вид определяемого стандартом поведения. Теперь, конструкции для которых поведение было неопределено(UB), считаются conditionally-supported и могут интерпретировать либо как implementation-defined, либо как ill-formed. Замена некоторых UB на Diagnosable Errors К примеру, теперь передача non-POD в элипсис приведёт к ошибке компиляции, а не к UB как в C++03. Новая модель выполнения программы В связи с добавлением оффициальной поддержки multithreading. Убрали понятие sequence point. Добавили понятие evaluation - набор выборок(чтение значения переменной) и side effects, которые происходят в ходе вычисления выражения. Понятие sequence point заменили аж тремя понятиями sequencing constraints: sequenced before, unsequenced, indeterminately sequenced. Эти понятия - отношения между двумя evaluations A и B(A sequenced before B, A and B unsequenced, etc). Теперь порядок вычисления операндов не unspecified. Теперь evaluations of operands unsequenced ![]() В связи с отсутствием понятия sequence point вычисление операндов операторов "a && b", "a || b", "a ? b : c" и "a, b" примерно следующее: evaluation of a is sequenced before evaluation of b. Облегчение ограничений на POD'ы Ввели два новых понятия: trivial-class и standard-layout-class. POD - это класс, который является одновременно и trivial и standard-layout. Теперь все гарантии, которые давал POD можно разделить на 2 части: первые даются для trivial типов, вторые для standard-layout. В общем теперь большее кол-во типов будет поддаваться копированию посредством memcpy и т.п. Перегрузка операторов Рассматривается возможность перегрузки операторов . .* static_cast<> const_cast<> dynamic_cast<> [hr] Стандартная библиотека cstdint из C99 Добавленна опциональная поддержка типов с размером точно соответствующим указанному. int8_t, int16_t, int32_t, int64_t uint8_t, uint16_t, uint32_t, uint64_t Обязательная поддержка для типов с размером не меньшим указанного. int_least8_t, int_least16_t, etc. uint_least8_t, etc. И обязательная поддержка типов с размером точно соответствующим указанному, но, возможно, более быстрых, чем их least-эквиваленты. int_fast8_t, etc. uint_fast8_t, etc. Контейнеры Sequence container: std::array - см. ниже "Перешло из boost". Unordered associative containers: unordered_map, unordered_multimap, unordered_set, unordered_multiset Вполне ожидаемые контейнеры работающие по принципу хэширования, ранее известные под названием hash_set/map в "вольных" реализациях STLport, MS VC-8.0. В связи с введением rvalue-reference и move semantics Во-первых, повсеместное добавление/переведение вышеобозначенной семантики для повышения производительности(там, где это возможно). Добавлены ф-ции помошники move и forward, означающие не что иное, как прямое предназначение rvalue-ссылок. Первая вынуждает использовать семантику перемещения даже если операнд - lvalue(-reference). Вторая осуществляет необходимые телодвижения для достижения perfect forwarding ![]() Добавлен move_iterator< class Iter >, который работает точно также, как Iter, за исключением того, что его dereferencing оператор принуждает использовать семантику перемещения. В связи с введением constexpr Много где встречаются эти константные ф-ции(результат которых можно использовать даже для определения статического массива). К примеру numeric_limits. Теперь его ф-ции min/max отвечают соответствующим требованиям. Перешло из boost std::tuple Тож самое, что и boost::tuple, за одним отличием - переведён на синтаксис variadic templates. std::bind Тож самое, что и boost::bind, за одним отличием - переведён на синтаксис variadic templates. std::array(sequence container) Тож самое, что и boost::array. Вроде где-то упоминалось, что собираются сделать его N-мерным(в отличие от 1-мерного boost::array). std::regex См. boost::regex Многопоточность Ничего не могу сказать более определённого, чем то, что в новом С++ будет поддержка многопоточности и будет предоставленно API, совместимое с posix pthreads. Также, возможность выполнения атомарных операций(необходимо для синхронизации - реализации спин-локов) P.S. Обсуждение упомянутых фич, а также, изложение информации о неупомянутых фичах очень даже приветствуется :wub: Добавлено через 10 минут и 23 секунды Ну, по большей части - да... а даже, если нет, то комитет это не остановит от выпуска нового стандарта... Комитет специально после 1998 first edition почти не сделал никаких новых фич, выпуская 2003 second edition, известный внутри комитета, как "service pack 1" ![]() Нет. По идее, кодить можно будет уже в 2009 т. к. в 2007 будет выпущен final candidate document, который к 2009 почти без изменений станет новым стандартом. Специально сделано, чтобы разработчики успели сделать соответствующие стандарту реализации. Это сообщение отредактировал(а) archimed7592 - 12.6.2007, 14:16 -------------------- If you have an apple and I have an apple and we exchange apples then you and I will still each have one apple. But if you have an idea and I have an idea and we exchange these ideas, then each of us will have two ideas. © George Bernard Shaw |
||||||||||||||||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||||||||||||||||
JackYF |
|
|||
![]() полуавантюрист ![]() ![]() ![]() ![]() Профиль Группа: Участник Сообщений: 5814 Регистрация: 28.8.2004 Где: страна тысячи озё р Репутация: 18 Всего: 162 |
Что понравилось/долго ждали:
Вот этого не понял... Понял, но не поддерживаю ![]() Ничего. Даже если так (хотя уже ответил archimed7592, что не совсем так), то полезность большинства фич очень и очень в плюс. |
|||
|
||||
nerezus |
|
|||
![]() Вселенский отказник ![]() ![]() ![]() ![]() Профиль Группа: Участник Сообщений: 3330 Регистрация: 15.6.2005 Репутация: 3 Всего: 43 |
и наконец-то в 2009 году появятся потоки...
ждем поддержку файловой системы в 2014 и сокетов в ~2049 Это сообщение отредактировал(а) nerezus - 12.6.2007, 15:12 |
|||
|
||||
JackYF |
|
|||
![]() полуавантюрист ![]() ![]() ![]() ![]() Профиль Группа: Участник Сообщений: 5814 Регистрация: 28.8.2004 Где: страна тысячи озё р Репутация: 18 Всего: 162 |
boost::thread появился раньше. ну-ну ![]() |
|||
|
||||
archimed7592 |
|
||||||
![]() Архимед ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2531 Регистрация: 12.6.2004 Где: Moscow Репутация: 58 Всего: 93 |
к примеру, все классы, расчитанные на динамическое использование запрещают копирование своих экземпляров
В С++09 добавили такой спецификатор доступа, который делает запрет даже ф-циям членам.
А зря. Это такой же синтасический сахар, как const.
К тому же способствует самодокументированию кода. К примеру, собираются ввести(после С++09) preconditions, postconditions и invariants - вещи, которые нафик не нужны(как и концепции), но способствуют написанию устойчивого клиентского кода и самодокументированного библиотечного кода. Называется фича, кстати, "контрактное программирование" ![]() Добавлено через 1 минуту и 7 секунд Нет. Всё это будет в TR2, который выйдет чуть позже стандарта. -------------------- If you have an apple and I have an apple and we exchange apples then you and I will still each have one apple. But if you have an idea and I have an idea and we exchange these ideas, then each of us will have two ideas. © George Bernard Shaw |
||||||
|
|||||||
JackYF |
|
|||
![]() полуавантюрист ![]() ![]() ![]() ![]() Профиль Группа: Участник Сообщений: 5814 Регистрация: 28.8.2004 Где: страна тысячи озё р Репутация: 18 Всего: 162 |
О, теперь допер. Еще раз спасибо. ну... не знаю, не знаю... с этим просто граблей не было никогда, в отличие от всего остального... это лично мое мнение. Введут - и хорошо. Может, и я оценю со временем. |
|||
|
||||
archimed7592 |
|
|||
![]() Архимед ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2531 Регистрация: 12.6.2004 Где: Moscow Репутация: 58 Всего: 93 |
Классический сценарий: базовый интерфейс представляет несколько ф-ций с декларатором virtual. В производных классах эти ф-ции подменяются, но, т.к. стандарт разрешает не писать virtual в производных классах, то некоторые его не пишут(да даже если пишут - сути дела не меняет). Так вот. Кто-то очепятался и длинное имя ф-ции написал неправильно. Если стандарт кодирования принуждает писать "> 0" для переопределённых ф-ций(и этот суффикс был написан), то компилятор ругнётся. Если нет - всё скомпилится и ошибку будут искать достаточно долго. -------------------- If you have an apple and I have an apple and we exchange apples then you and I will still each have one apple. But if you have an idea and I have an idea and we exchange these ideas, then each of us will have two ideas. © George Bernard Shaw |
|||
|
||||
JackYF |
|
|||
![]() полуавантюрист ![]() ![]() ![]() ![]() Профиль Группа: Участник Сообщений: 5814 Регистрация: 28.8.2004 Где: страна тысячи озё р Репутация: 18 Всего: 162 |
Если в базовом классе было прописано virtual ... (...) = 0, то в этом случае тоже компилятор ругнется. Он не сможет инстанцировать базовый абстрактный класс.
|
|||
|
||||
archimed7592 |
|
|||
![]() Архимед ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2531 Регистрация: 12.6.2004 Где: Moscow Репутация: 58 Всего: 93 |
JackYF, ну а если не было? Если базовый класс предоставляет поведение по умолчанию? как в std::basic_streambuf, к примеру, там очень уж труднопроизносимые имена ф-ций... Вот с ... (...) > 0 при неправильно записанном имени будет ошибка компиляции. Без > 0 - не будет. Удобно? Удобно.
![]() -------------------- If you have an apple and I have an apple and we exchange apples then you and I will still each have one apple. But if you have an idea and I have an idea and we exchange these ideas, then each of us will have two ideas. © George Bernard Shaw |
|||
|
||||
JackYF |
|
|||
![]() полуавантюрист ![]() ![]() ![]() ![]() Профиль Группа: Участник Сообщений: 5814 Регистрация: 28.8.2004 Где: страна тысячи озё р Репутация: 18 Всего: 162 |
Ну пускай будет ![]() Станет лучше - хорошо. Не привыкнул как-то. Блин, заканчиваю... опять повесть пишу. Короче, я понял, зачем это надо. Понравится-таки - буду применять. |
|||
|
||||
bsa |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 9185 Регистрация: 6.4.2006 Где: Москва, Россия Репутация: 63 Всего: 196 |
Не очень понял про alignof и alignas.
|
|||
|
||||
archimed7592 |
|
|||
![]() Архимед ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2531 Регистрация: 12.6.2004 Где: Moscow Репутация: 58 Всего: 93 |
alignof(T) возвращает выравнивание для заданного типа. alignas(T) или alignas(size_t const) задаёт выравнивание. T1 alignas(T1) alignas(T2) x; - делаем выравнивание по T2, но только в том случае, если оно больше чем у T1(родного типа). Делается так потому, что на некоторых платформах выравнивание меньшее, чем родное может вызвать аппаратное исключение. -------------------- If you have an apple and I have an apple and we exchange apples then you and I will still each have one apple. But if you have an idea and I have an idea and we exchange these ideas, then each of us will have two ideas. © George Bernard Shaw |
|||
|
||||
bsa |
|
||||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 9185 Регистрация: 6.4.2006 Где: Москва, Россия Репутация: 63 Всего: 196 |
Выравнивание - это фактическое место в памяти (расстояние между соседними объектами в байтах)?
Про исключение совсем не понял. Если T1 - какой-то класс (или тип данных), а T2 - другой класс, то запись:
Или все это нужно лишь для гарантированного размещения байта (например) в структуре без указания всяких __attribute__(pack) (или как оно)? Но тогда опять не совсем понятно, а причем тут исключение? |
||||
|
|||||
![]() ![]() ![]() |
Правила форума "С++:Общие вопросы" | |
|
Добро пожаловать!
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn |
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |