Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
||
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[18.119.127.230] |
|
Страницы: (78) 1 [2] 3 4 ... 77 78 ( Перейти к последнему сообщению ) |
Сообщ.
#16
,
|
|
|
Цитата Unreal Man @ Не совсем понял, как sizeof может помочь в передаче не-POD'а в элипсис(в printf, к примеру) так, чтобы это не повлекло UB. Приведи пример.Сейчас можно обернуть такой вызов в sizeof, и тогда никакого undefined behavior нет. Цитата Unreal Man @ С export template связаны некоторые проблемы реализации. Что же касается выше обозначенных фич - никаких проблем при реализации возникнуть не должно. К слову уже сейчас можно скачать расширения g++ для поддержки variadic templates, concepts. расширение vs-8.0 для поддержки template aliases и т.д.Ага, молитесь ещё, чтоб всё это поддерживалось новыми компиляторами А то глядишь – к великолепной поддержке template export ещё много чего добавится сам то понимаешь, что это не совсем разумное решение будет? в изначальном документе, предлагающем move semantics было озвучено, что вроде как реализовать это можно и без rvalue-references чисто библиотечным путём: template <class T> class move_t { const T& t; public: move_t(const T& a) : t(a) {} operator T&(){ return t; /* тут видимо забыли const_cast, но я привожу дословно :) */ } }; struct A { A(const A &); // copy ctor A(move_t<A>); // move ctor }; И тем не менее, поддержка на уровне языка мне нравится больше |
Сообщ.
#17
,
|
|
|
Цитата archimed7592 @ Модулей в C++09 не будет. Скорее всего сделают отдельным TR. А может и до следующего стандарта отложат. Похоже, что да... И так фич новых много. Цитата Gunnar @ Ну и сборщик мусора на мой взгляд - лишний. Был один язык лишенный этого греха, и тот сдался. Сборщик мусора полезен А проблема сборщиков во многих языков в том, что он неотключаем и некоторые вещи (типа RAII) с ним несовместимы. Здесь же планируется опциональный (т.е., указывается, к чему его надо применять, а к чему — нет). Поэтому комбинируются лучшие стороны — если нужен GC, он просто включается, а если не нужен, то он не мешает. Цитата Unreal Man @ Ага, молитесь ещё, чтоб всё это поддерживалось новыми компиляторами А то глядишь – к великолепной поддержке template export ещё много чего добавится Цитата archimed7592 @ К слову уже сейчас можно скачать расширения g++ для поддержки variadic templates, concepts. В g++ (версии 4.3 и в CVS HEAD) (и comeau) уже поддерживается часть новых фишек. Обещают добавлять туда поддержку фич по мере продвижения процесса голосования по ним. Так что к 2009 году наверняка будет по крайней мере два компилятора, обладающих хорошей поддержкой. msvc тоже наверняка будет поддерживать. |
Сообщ.
#18
,
|
|
|
Кстати, по части шаблонов в C++ нередко не хватает чего-то вроде static if (см. digitalmars.D.learn - static assert / static if)
|
Сообщ.
#19
,
|
|
|
Цитата mo3r @ Похоже, что да... И так фич новых много. Точно тебе говорю . Со слов Саттера(да и комитета в общем) в С++09 этого не будет. Цитата Unreal Man @ во-первых, есть #if #else #endif, во-вторых, озвученная в указанной тобой статье проблема решается с помощью описанных в первом посте "Generalized Constant Expressions" Кстати, по части шаблонов в C++ нередко не хватает чего-то вроде static if |
Сообщ.
#20
,
|
|
|
Цитата archimed7592 @ Не совсем понял, как sizeof может помочь в передаче не-POD'а в элипсис(в printf, к примеру) Не, тут другое дело. Иногда (у меня так почти всегда) эллипсис применяется для игр с перегрузкой функций, где результат перегрузки становится извествен благодаря sizeof (то, что внутри sizeof, не вычисляется в run-time). Пример можешь посмотреть здесь. Вот будет ли такое работать согласно новому стандарту? Цитата archimed7592 @ сам то понимаешь, что это не совсем разумное решение будет? Это почему же? Добавлено Цитата archimed7592 @ во-первых, есть #if #else #endif Ну, эт совсем не то. Препроцессор тем и плох, что он препроцессор С шаблонами его не поюзаешь. Цитата archimed7592 @ озвученная в указанной тобой статье проблема решается с помощью описанных в первом посте "Generalized Constant Expressions" Покажи, каким образом. Добавлено Проблема с выбором у меня часто такая: нужно в зависимости от некоторого условия выбрать их двух или более шаблонных классов один в качестве typedef-а некоего типа, причём инстанцироваться должен только выбранный тип. Реализация такого выбора в C++ – геморрой редкостный. |
Сообщ.
#21
,
|
|
|
Цитата Unreal Man @ Ну, раз другое дело... то и разговор другой и о другом Не, тут другое дело. Цитата Unreal Man @ Будет. Почти всё, что работало до этого работать будет.Вот будет ли такое работать согласно новому стандарту? По указанной тобой ссылке я не нашёл передачи не-POD'а в элипсис. Цитата Unreal Man @ Потому что это уже будет специальный тип в который будет пробинден this. А зачем? Много ньюансов и подводных камней. И опять же, зачем? Кому и для чего это нужно? В стандарт включают вещи, которые кому-то и зачем-то нужны.Это почему же? И, в конце концов, для этого есть bind или mem_fn. Считай, что результат, возвращённый mem_fn является тем самым типом Цитата Unreal Man @ Покажи, каким образом. constexpr int fact(int n) { if (n > 0) return fact(n - 1); else return 1; } double array[fact(5)]; // C++09 well-formed Добавлено Цитата Unreal Man @ эээ... либо я чего-то не понял, либо:Проблема с выбором у меня часто такая: нужно в зависимости от некоторого условия выбрать их двух или более шаблонных классов один в качестве typedef-а некоего типа, причём инстанцироваться должен только выбранный тип. Реализация такого выбора в C++ – геморрой редкостный. template < bool Condition, class TrueType, class FalseType > struct select; template < class TrueType, class FalseType > struct select< true, TrueType, FalseType > { typedef TrueType type; }; template < class TrueType, class FalseType > struct select< false, TrueType, FalseType > { typedef FalseType type; }; template < int N > struct A { typedef typename select< (N > 0), vector< bool >, bitset< 256 > >::type container_t; // ... }; Добавлено Прочитал все доступные на сайте комитета документы по GC. Пока толком не понял как коллектор будет реализовываться. Чего-то они там перемудрили со "сканированием памяти на предмет поиска указателей". Нафик сканировать массив char * и искать в нём указатели? |
Сообщ.
#22
,
|
|
|
Это явно под влиянием Java. Там это выглядит практически аналогично. С одной стороны это удобно, с другой стороны это будет, видимо, первый случай высокоуровневого примитива в языке.
|
Сообщ.
#23
,
|
|
|
Цитата archimed7592 @ По указанной тобой ссылке я не нашёл передачи не-POD'а в элипсис. Я показал смысл использования эллипсиса. Передача не-POD-объекта может быть, например, при проверке конвертируемости объекта одного типа в объект другого типа (у Александреску это, вроде, было). Цитата archimed7592 @ Потому что это уже будет специальный тип в который будет пробинден this. А зачем? Много ньюансов и подводных камней. Каких подводных камней? Цитата archimed7592 @ И опять же, зачем? Это к вопросу «а зачем нужно использовать операторы?» Цитата archimed7592 @ И, в конце концов, для этого есть bind Ну да, а ещё есть, например, std::plus: int x, y; ... // ну зачем же тут писать x+y, когда есть такой красивый способ? int result = std::plus<int>()(x, y); Цитата archimed7592 @ эээ... либо я чего-то не понял, либо В том-то и дело, что это «либо» годится далеко не всегда. Недостаток этого способа в том, что он требует инстацирования обоих выбираемых типов, что иногда неприемлемо: тип, остающийся невыбранным, в ряде случаев не может быть успешно инстанцирован, из-за чего ты будешь хватать ошибки компиляции. Для реализации такого выбора приходится писать вспомогательный шаблон – на каждый случай свой. |
Сообщ.
#24
,
|
|
|
Цитата Unreal Man @ implicitly инстанцирований, если не ошибаюсь. Не могу придумать такого клинического случая, чтобы implicitly инстанцирование упало. Хоть с enable_if извращайся... Недостаток этого способа в том, что он требует инстацирования |
Сообщ.
#25
,
|
|
|
Стандартная библиотека C++09
Более подробный обзор библиотечных изменений. numeric_limits::max_digits10 digits10 означает(как и в C++03) кол-во десятичных цифр, которые не потеряют в точности после некоторых вычислений. max_digits10 означает кол-во десятичных цифр, которые тип вообще способен хранить. iostream manipulator: defaultfloat Манимулятор делает unsetf(ios_base::floatfield). Т.е. убирает эффект ранее применённых манипуляторов fixed или scientific. Может кому-то это и понадобится . Скорее новичкам. Усовершенствованное использование const_iterator Во-первых, с введением auto, следующий код будет использовать iterator, даже когда желаемым является использование const_iterator. vector< int > v; for (auto it = v.begin(); i != v.end(); ++i) { /* ... */ } // такой workaround не подходит в общем случае // т.к. iterator и const_iterator по идее имеют право быть // совершенно разными и несовместимыми типами for (const auto it = v.begin(); i != v.end(); ++i) { /* ... */ } Также, в практике очень часто встречаются случаи, когда желаемо использование именно константного итератора в целях безопасности. К примеру, в ФП для этого приходится применять обёртки типа boost::cref или boost::lambda::constant_ref. Пример из соответствующего документа(блин, как будет proposal по русски? ) void reset( double & d ) { d = 0.0; } void resee( double d ) { cout << ' ' << d; } vector<double> v; // распечатать v ... for_each( v.begin(), v.end(), reset ); // oops: хотели написать resee В связи с этим для всех STL-совместимых контейнеров ввели новые ф-ции const_iterator cbegin() const; const_iterator cend() const; // для реверсивных контейнеров const_reverse_iterator crbegin() const; const_reverse_iterator crend() const; Теперь можно со спокойной душой писать auto it = v.cbegin() и не опасаться случайного изменения данных. void reset( double & d ) { d = 0.0; } void resee( double d ) { cout << ' ' << d; } vector<double> v; // распечатать v ... for_each( v.cbegin(), v.cend(), reset ); // oops: compile-time error Заметьте тенденцию, как на С++ становится всё проще и проще писать всё более и более надёжный код. Чем дальше залезаю, тем больше понимаю, что С++ идеален и ни один холивар не докажет мне обратного next, prior Аналоги std::advance, но в отличие от advance возвращают изменённый итератор(точнее новый, равный изменённому). is_sorted, is_heap Помошники в собственных реализациях алгоритмов сортировки. Diagnostics Enhancements В связи с тем, что системно-зависимые телодвижения сообщают об ошибках немного иначе, чем принято в С++, а именно, ошибку описывает некое магическое число, добавили новых типов, для обёртывания этих чисел в исключения. Этот пункт рассчитывался для включения в TR2 т.к. там появятся FileSystem и Networking, но, т.к. в С++09 появились потоки, которые тоже порой "ошибаются", решили включить этот документ в стандарт. Итак, теперь errno.h является почти полностью соответствующим POSIX. В нём теперь определены макросы E2BIG, EACCESS, и т.д. Добавлен хэдер <system_error> определяющий следующие типы(и переменные): class system_error; class error_code; class error_category; extern const error_category& posix_category; extern const error_category& native_category; enum posix_errno { file_too_large, file_exists, // ... }; system_error - наследник runtime_error. Собственно говоря, потоковая, файловая и сетевая библиотеки будут бросать исключения именно этого(или унаследованного от этого) типа. error_code - обёрточка для "магического числа". error_category и иже с ним - определяет является ли ошибка posix-совместимая или же "родная" для системы. posix_errno - перечисление, члены которого являются эквивалентами соответствующих ошибок EXXXX. minmax, minmax_element minmax(a, b) - возвращает упорядоченную пару значений, эквивалентную make_pair(min(a,b), max(a,b)). minmax_element(first, last) - возвращает упорядоченную пару итераторов make_pair(min_element(first, last), max_element(first, last))(минимальный и максимальный в последовательности). И две соответствующие перегрузки для использования с заданным предикатом(вместо используемого по умолчанию operator<). long long goes to the Library В связи с оффициальным статусом "новых" интегральных типов `long long` и `unsigned long long` стандартная библиотека обзавелась возможностями работы с этим типом(numeric_limits, hash, iostreams). Unicode-строки В связи с введением двух новых типов - char16_t и char32_t(а также литералов u"..." и U"..."), сделали поддержку UTF-16 и UTF-32 строк. Рассматривается возможность добавления несовместимого с basic_string класса для UTF-8(литерал E"..."). UTF-16 в большинстве случаев представляет одну букву одним символом, а суррогаты(в случае их неправильной интерпретации) могут повредить только одну букву(рядом с которой они находятся). UTF-32 во всех случаях представляет одну букву одним символом. В связи с этим для представления UTF-16/32-строк вполне подходит basic_string. Добавлены специализации char_traits<char16_t> char_traits<char32_t> basic_string<char16_t> = u16string basic_string<char32_t> = u32string hash<char16_t> hash<char32_t> hash<u16string> hash<u32string> Незначительные изменения type_traits Исправлено около 40 проблем. Добавлены средства для lvalue/rvalue-references. Немного модифицированны характеристики конструкторов(в связи с облегчением ограничений на POD'ы и введением trivial-type и standard-layout-type). Random Number Generation Предложений улучшить средства стандартной библиотеки генерирования псевдослучайных чисел было великое множество. Тот же TR1 включает в себя некоторые. Всё это было пересмотренно, переработанно обобщено и, наконец то, включенно в стандарт. Те кто знаком с boost::random могут не читать - поменялись только названия(ну и, может быть, добавлены новые генераторы). Имеет смысл распределения. Представляет из себя функтор, который на вход берёт объект, отвечающий концепции Uniform random number generator, на выходы даёт распределение относительно параметра p(который задаётся при конструкции распределения или как второй аргумент функтора). Включённых в стандарт распределений(отвечающих концепции) много, список приводить смысла, думаю, не имеет. Адаптация стандартной библиотеки к rvalue-references Введены концепции MoveConstructible и MoveAssignable. Их смысл, думаю, должен быть понятен auto_ptr объявлен устаревшим(deprecated), а на его замену пришёл unique_ptr. unique_ptr отличается от auto_ptr тем, что у него есть возможность задавать deleter. Также, он разработан в расчёте на семантику перемещения и его конструктор копирования и копирующий оператор присваивания запрещены(недоступны). Есть две частичные специализации для массивов переменной длины и для массивов фиксированной длины. Как уже было упомянуто в первом посте, для rvalue-ссылок сделаны ф-ции помощники move и fwd. Также добавились алгоритмы move, move_backward, предназначенные для "разрушающего std::copy" К алгоритмам, которые изменяют последовательность путём перемещения/переставления элементов(sort, merge, etc.) добавлены требования на тип элемента: помимо того, что он должен был быть Swappable, он теперь ещё должен быть MoveConstructible и MoveAssignable. Использовать unique_ptr теперь можно намного более надёжно, чем это было с auto_ptr. void f(unique_ptr< int >); unique_ptr< int > up1(new int(7)); unique_ptr< int > up2 = up1; // compile-time error unique_ptr< int > up3 = move(up1); // ok f(up3); // compile-time error f(move(up3)); // ok unique_ptr< int[] > uparr(new int[256]); // за счёт специализации выберется правильный deleter(delete[] ptr). unique_ptr< IInterface > f2() { class Realization : public IInterface { /* ... */ }; // ... if (/* ... */) return unique_ptr< IInterface >(new Realization(/* ... */)); // ok unique_ptr< IInterface > up(new Realization(/* ... */)); // ... return up; // compile-time error return move(up); // ok } <iostream> - header dependency Наконец то . Теперь хэдер <iostream> подключает <ios>, <streambuf>, <istream> и <ostream>. Вам возможно смешно, но, на самом деле, по стандарту(а мы говорим именно о нём ), подключив только <iostream> нельзя использовать ни std::endl, ни операторы << и >>(и это только один из примеров). Т.е. по стандарту многие программы могут просто не компилироваться. Зная это я всегда писал #include <ostream> и #include <istream> и лично меня это телодвижение немного напрягало. Также подумывают о создании отдельного хэдера <std>, включающего всю стандартную библиотеку(актуально для очень маленьких программ или проектов в которых используются precompiled headers). enable_if, conditional "Новые" шаблончики. Давно используются сообществом и пришли из boost. enable_if предназначен для манипулирования принципом SFINAE на основе некоторого статического условия. conditional позволяет выбрать один из двух типов на основе некоторого статического условия. Внедрение std::string В стандарте было около 20 мест, где использовался тип char * для передачи строки. Везде добавили перегруженные эквиваленты для std::string. В основном затронуты локализация и fstreams.(ifstream::open, к примеру). Yet another type-trait: decay template < class T > struct decay { typedef /* см.ниже */ type; }; // Если T - массив, т.е. T <=> U[] или U[N], то decay< T >::type есть U *. // Eсли T - фунция, т.е. T <=> R(A1, A2, ...), то decay< T >::type есть T *, т.е. указатель на ф-цию. Variadic Templates в стандартной библиотеке Как уже было упомянуто, в библиотеке появилось следующее: template <class... Types> class tuple; template<class Fn, class... Types> /* unspecified */ bind(Fn, Types...); template<class R, class Fn, class... Types> /* unspecified */ bind(Fn, Types...); template<class Function> class function; // undefined template<class R, class... ArgTypes> class function<R(ArgTypes...)>; tuple - во-первых, может использоваться как идиома "списки типов". Во-вторых, может использоваться как std::pair на произвольное кол-во типов(и элементов). bind - биндер из boost. function - обёртка обобщённого функтора(тоже из boost). TR1. Technical Report on C++ Library Extensions Ну и конечно же tr1. С теми или иными модификациями, он полностью включенн в стандарт. Почти все сущности перенесены из пространства имён std::tr1 в пространство имён std. Про содержание tr1 в следующий раз . Добавлено описание TR1. Здесь описаны(упомянуты) далеко не все на текущий момент нововведения и исправления в Стандартной Библиотеке. Обсуждение, дополнения и коррективы приветствуются. Всем спасибо за внимание. remark: добавленна ссылка на продолжение(TR1): TR1. Technical Report on C++ Library Extensions. Сообщения были разделены в тему "Грамматика C++" |
Сообщ.
#26
,
|
|
|
Цитата archimed7592 @ блин, как будет proposal по русски? Предложение Цитата archimed7592 @ UTF-16 в большинстве случаев представляет одну букву одним символом, а суррогаты(в случае их неправильной интерпретации) могут повредить только одну букву(рядом с которой они находятся). UTF-32 во всех случаях представляет одну букву одним символом. В UTF-32 один endpoint кодируется фиксированным набором байтов. Но одна буква может занимать более одного endpoint'а. Цитата http://unicode.org/faq/char_combmark.html#7 Q: How should characters (particularly composite characters) be counted, for the purposes of length, substrings, positions in a string, etc. A: In general, there are 3 different ways to count characters. Each is illustrated with the following sample string. "a" + umlaut + greek_alpha + \uE0000. (the latter is a private use character) 1. Code Units: e.g. how many bytes are in the physical representation of the string. Example: In UTF-8, the sample has 9 bytes. [61 CC 88 CE B1 F3 A0 80 80] In UTF-16BE, it has 10 bytes. [00 61 03 08 03 B1 DB 40 DC 00] In UTF-32BE, it has 16 bytes. [00 00 00 61 00 00 03 08 00 00 03 B1 00 0E 00 00] 2. Codepoints: how may code points are in the string. The sample has 4 code points. This is equivalent to the UTF-32BE count divided by 4. 3. Graphemes: what end-users consider as characters. A default grapheme cluster is specified by the Unicode Standard 4.0, and is also in UTR #18 Regular Expressions at http://www.unicode.org/reports/tr18/. The choice of which one to use depends on the tradeoffs between efficiency and comprehension. For example, Java, Windows and ICU use #1 with UTF-16 for all low-level string operations, and then also supply layers above that provide for #2 and #3 boundaries when circumstances require them. This approach allows for efficient processing, with allowance for higher-level usage. However, for a very high level application, such as word-processing macros, graphemes alone will probably be sufficient. [MD] Добавлено Opaque typedef (http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1891.pdf) Появятся новые виды typedef'ов, которые позволят создать новый тип, который ведет себя точно так же, как и какой-то другой, но между ними не будет неявного преобразования. Полезно, например, когда какой-то примитивный тип по всем свойствам подходит для описания чего-либо (например, координаты или физические величины или хэндлы объектов ОС), но неявные преобразования нежелательны. Пример: opaque typedef double X, Y, Z; // Cartesian 3D coordinate types opaque typedef double Rho, Theta, Phi; // polar 3D coordinate types class PhysicsVector { public: PhysicsVector(X, Y, Z); PhysicsVector(Rho, Theta, Phi); ... }; // PhysicsVector |
Сообщ.
#27
,
|
|
|
Ура. Очень разд этой виче. Только не понял.. (может не очень внимательно читал...?) ссылка на ссылку как..? Опять запрещена? ведь T&& это rValue reference а не ссылка на ссылку.. (( Добавлено Цитата LuckLess @ T&& это rValue reference вообще имхо не лучшее обозначение. лучшеб там.. ну хотябы T^ rvalueRef; |
Сообщ.
#28
,
|
|
|
Цитата archimed7592 @ implicitly инстанцирований, если не ошибаюсь. Не понимаю, к чему ты клонишь. Кстати, выбором типа проблема не ограничивается. Например, тебе нужно сделать swap для объектов двух неизвестных типов. Какие тут могут быть варианты? Кто-то может реализовать у своего класса метод с именем swap, кто-то другой – с именем Swap, ещё кто-то может вообще такой метод не реализовывать, тогда остаётся только вызвать std::swap. Вот примерная реализация функции, вызывающей нужный swap, которая могла бы получиться со static if: template <class T> void MakeSwap(T &a1, T &a2) { static if (CHECK_METHOD(swap, void (T &))) // реализацию макроса CHECK_METHOD скипаю a1.swap(a2); else if (CHECK_METHOD(Swap, void (T &))) a1.Swap(a2); else std::swap(a1, a2); } Насколько всё лаконично, просто и понятно. А теперь сравни вот с этим извращением template <class T> void MakeSwapHelper(T &a1, T &a2, IntToType<0>) { a1.swap(a2); } template <class T> void MakeSwapHelper(T &a1, T &a2, IntToType<1>) { a1.Swap(a2); } template <class T> void MakeSwapHelper(T &a1, T &a2, IntToType<2>) { std::swap(a1, a2); } template <class T> void MakeSwap(T &a1, T &a2) { const int variant = CHECK_METHOD(swap, void (T &)) ? 0 : CHECK_METHOD(Swap, void (T &)) ? 1 : 2; MakeSwapHelper(a1, a2, IntToType<variant>()); } Цитата archimed7592 @ Хоть с enable_if извращайся... А при чём тут, собственно, enable_if? |
Сообщ.
#29
,
|
|
|
Цитата Unreal Man @ Кто-то может реализовать у своего класса метод с именем swap, кто-то другой – с именем Swap, ещё кто-то может вообще такой метод не реализовывать Это к психиатру, однозначно. Если есть соглашения, им нужно следовать, если нет - их нужно принять. Если тип из 3-парти либы, к нему нужно написать адаптер, который реализует соглашения. Добавлено а если найдутся умники которые реализуют методы sWap, svap, SWaP, pomenyat_mestami, и.т.д. Ты их тоже в статик иф засунешь??? Бред! |
Сообщ.
#30
,
|
|
|
Цитата LuckLess @ когда-то была разрешена? ссылка на ссылку как..? Опять запрещена? Цитата LuckLess @ ведь T&& это rValue reference а не ссылка на ссылку.. (( ты наверное не понял, что && - интерпретируется как отдельный токен т.е. typedef int & rint; typedef rint & rint2; // rint2 <=> rint <=> int & и так было, если не ошибаюсь аж с C++98 typedef int && rrint; // rrint - не то же самое, что rint2 typedef rrint & rint3; // rint3 <=> int && & <=> int & - по одному из правил сворачиваем ссылку Цитата LuckLess @ ну хотябы T^ rvalueRef; есть ещё такой момент, что T^ - используется в C++/CLI, а C++/CLI используется микрософтом, а в микрософте работает Герб Саттер, а он председатель комитета, если не ошибаюсь ещё есть момент, что C++/CLI тоже разрабатывался комитетом. |