На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
Модераторы: Qraizer, Hsilgos
Страницы: (77) 1 [2] 3 4 ...  76 77  ( Перейти к последнему сообщению )  
> Текущий Стандарт С++ и перспективы его развития
    Цитата Unreal Man @
    Сейчас можно обернуть такой вызов в sizeof, и тогда никакого undefined behavior нет.
    Не совсем понял, как sizeof может помочь в передаче не-POD'а в элипсис(в printf, к примеру) так, чтобы это не повлекло UB. Приведи пример.


    Цитата Unreal Man @
    Ага, молитесь ещё, чтоб всё это поддерживалось новыми компиляторами :D А то глядишь – к великолепной поддержке template export ещё много чего добавится :lol:
    С export template связаны некоторые проблемы реализации. Что же касается выше обозначенных фич - никаких проблем при реализации возникнуть не должно. К слову уже сейчас можно скачать расширения g++ для поддержки variadic templates, concepts. расширение vs-8.0 для поддержки template aliases и т.д.


    Цитата Unreal Man @
    Лучше б они для результата встроенного оператора –>* тип ввели.
    сам то понимаешь, что это не совсем разумное решение будет?



    Цитата Unreal Man @
    Я на данный момент реализую это примерно так:
    в изначальном документе, предлагающем move semantics было озвучено, что вроде как реализовать это можно и без rvalue-references чисто библиотечным путём:
    ExpandedWrap disabled
        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
      };
    Не знаю, насколько это всё будет работать, но, в первом приближение - вполне себе будет работать :)
    И тем не менее, поддержка на уровне языка мне нравится больше :)
      Цитата archimed7592 @
      Модулей в C++09 не будет. Скорее всего сделают отдельным TR. А может и до следующего стандарта отложат.

      Похоже, что да... И так фич новых много.
      Цитата Gunnar @
      Ну и сборщик мусора на мой взгляд - лишний. Был один язык лишенный этого греха, и тот сдался.

      Сборщик мусора полезен :) А проблема сборщиков во многих языков в том, что он неотключаем и некоторые вещи (типа RAII) с ним несовместимы. Здесь же планируется опциональный (т.е., указывается, к чему его надо применять, а к чему — нет). Поэтому комбинируются лучшие стороны — если нужен GC, он просто включается, а если не нужен, то он не мешает.
      Цитата Unreal Man @
      Ага, молитесь ещё, чтоб всё это поддерживалось новыми компиляторами :D А то глядишь – к великолепной поддержке template export ещё много чего добавится :lol:

      Цитата archimed7592 @
      К слову уже сейчас можно скачать расширения g++ для поддержки variadic templates, concepts.

      В g++ (версии 4.3 и в CVS HEAD) (и comeau) уже поддерживается часть новых фишек. Обещают добавлять туда поддержку фич по мере продвижения процесса голосования по ним. Так что к 2009 году наверняка будет по крайней мере два компилятора, обладающих хорошей поддержкой. msvc тоже наверняка будет поддерживать.
        Кстати, по части шаблонов в C++ нередко не хватает чего-то вроде static if (см. digitalmars.D.learn - static assert / static if)
          Цитата mo3r @
          Похоже, что да... И так фич новых много.

          Точно тебе говорю :). Со слов Саттера(да и комитета в общем) в С++09 этого не будет.

          Цитата Unreal Man @
          Кстати, по части шаблонов в C++ нередко не хватает чего-то вроде static if
          во-первых, есть #if #else #endif, во-вторых, озвученная в указанной тобой статье проблема решается с помощью описанных в первом посте "Generalized Constant Expressions"
            Цитата archimed7592 @
            Не совсем понял, как sizeof может помочь в передаче не-POD'а в элипсис(в printf, к примеру)

            Не, тут другое дело. Иногда (у меня так почти всегда) эллипсис применяется для игр с перегрузкой функций, где результат перегрузки становится извествен благодаря sizeof (то, что внутри sizeof, не вычисляется в run-time). Пример можешь посмотреть здесь. Вот будет ли такое работать согласно новому стандарту?

            Цитата archimed7592 @
            сам то понимаешь, что это не совсем разумное решение будет?

            Это почему же?

            Добавлено
            Цитата archimed7592 @
            во-первых, есть #if #else #endif

            Ну, эт совсем не то. Препроцессор тем и плох, что он препроцессор :) С шаблонами его не поюзаешь.

            Цитата archimed7592 @
            озвученная в указанной тобой статье проблема решается с помощью описанных в первом посте "Generalized Constant Expressions"

            Покажи, каким образом.

            Добавлено
            Проблема с выбором у меня часто такая: нужно в зависимости от некоторого условия выбрать их двух или более шаблонных классов один в качестве typedef-а некоего типа, причём инстанцироваться должен только выбранный тип. Реализация такого выбора в C++ – геморрой редкостный.
              Цитата Unreal Man @
              Не, тут другое дело.
              Ну, раз другое дело... то и разговор другой и о другом :)

              Цитата Unreal Man @
              Вот будет ли такое работать согласно новому стандарту?
              Будет. Почти всё, что работало до этого работать будет.
              По указанной тобой ссылке я не нашёл передачи не-POD'а в элипсис.


              Цитата Unreal Man @
              Это почему же?
              Потому что это уже будет специальный тип в который будет пробинден this. А зачем? Много ньюансов и подводных камней. И опять же, зачем? Кому и для чего это нужно? В стандарт включают вещи, которые кому-то и зачем-то нужны.
              И, в конце концов, для этого есть bind или mem_fn. Считай, что результат, возвращённый mem_fn является тем самым типом :tong:


              Цитата Unreal Man @
              Покажи, каким образом.

              ExpandedWrap disabled
                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++ – геморрой редкостный.
              эээ... либо я чего-то не понял, либо:
              ExpandedWrap disabled
                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 * и искать в нём указатели? :unsure:
              Сообщение отредактировано: trainer -
                Цитата Gunnar @
                Паскалюгой попахивает (или бейсиком??)
                Это явно под влиянием Java. Там это выглядит практически аналогично. С одной стороны это удобно, с другой стороны это будет, видимо, первый случай высокоуровневого примитива в языке.
                  Цитата archimed7592 @
                  По указанной тобой ссылке я не нашёл передачи не-POD'а в элипсис.

                  Я показал смысл использования эллипсиса. Передача не-POD-объекта может быть, например, при проверке конвертируемости объекта одного типа в объект другого типа (у Александреску это, вроде, было).

                  Цитата archimed7592 @
                  Потому что это уже будет специальный тип в который будет пробинден this. А зачем? Много ньюансов и подводных камней.

                  Каких подводных камней?

                  Цитата archimed7592 @
                  И опять же, зачем?

                  Это к вопросу «а зачем нужно использовать операторы?»

                  Цитата archimed7592 @
                  И, в конце концов, для этого есть bind

                  Ну да, а ещё есть, например, std::plus:

                  ExpandedWrap disabled
                    int x, y;
                    ...
                    // ну зачем же тут писать x+y, когда есть такой красивый способ?
                    int result  = std::plus<int>()(x, y);


                  Цитата archimed7592 @
                  эээ... либо я чего-то не понял, либо

                  В том-то и дело, что это «либо» годится далеко не всегда. Недостаток этого способа в том, что он требует инстацирования обоих выбираемых типов, что иногда неприемлемо: тип, остающийся невыбранным, в ряде случаев не может быть успешно инстанцирован, из-за чего ты будешь хватать ошибки компиляции. Для реализации такого выбора приходится писать вспомогательный шаблон – на каждый случай свой.
                    Цитата Unreal Man @
                    Недостаток этого способа в том, что он требует инстацирования
                    implicitly инстанцирований, если не ошибаюсь. Не могу придумать такого клинического случая, чтобы implicitly инстанцирование упало. Хоть с enable_if извращайся...
                      Стандартная библиотека 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.
                      ExpandedWrap disabled
                        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 по русски? :))
                      ExpandedWrap disabled
                        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-совместимых контейнеров ввели новые ф-ции
                      ExpandedWrap disabled
                        const_iterator cbegin() const;
                        const_iterator cend() const;
                         
                        // для реверсивных контейнеров
                        const_reverse_iterator crbegin() const;
                        const_reverse_iterator crend() const;

                      Теперь можно со спокойной душой писать auto it = v.cbegin() и не опасаться случайного изменения данных.
                      ExpandedWrap disabled
                        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> определяющий следующие типы(и переменные):
                      ExpandedWrap disabled
                        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.
                      Добавлены специализации
                      ExpandedWrap disabled
                        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.
                        Представляет из себя функтор, каждый вызов которого возвращает очередное (псевдо)случайное число.
                      • Random number engine.
                        Расширение концепции Uniform random number generator для того, чтобы генератор можно было создавать, копировать и управлять им(seed, discard, etc.).
                          Шаблонные классы, отвечающие концепции
                        • linear_congruential_engine
                        • mersenne_twister_engine
                        • subtract_with_carry_engine
                        • discard_block_engine
                        • independent_bits_engine
                        • shuffle_order_engine
                        • xor_combine_engine

                          Специализации шаблонных классов, отвечающих концепции
                        • minstd_rand0
                        • minstd_rand
                        • mt19937
                        • ranlux24_base
                        • ranlux48_base
                        • ranlux24
                        • ranlux48
                        • knuth_b
                      • Random number distribution.
                        Имеет смысл распределения.
                        Представляет из себя функтор, который на вход берёт объект, отвечающий концепции 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.
                      ExpandedWrap disabled
                        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
                        }
                      Т.е. теперь мы должны ясно выразить мысль, что мы хотим "отдать" объект(относится только к lvalue(-reference)).
                        Классы которые получили семантику перемещения(конструкторы, операторы(operator= и другие), swap, etc.).
                      • pair
                      • unique_ptr
                      • basic_string(string, wstring, u16string, u32string)
                      • containers(vector, list, deque, etc. все, кроме array). "Недоконтейнер" valarray тоже в этом списке.
                      • iterators(все итераторы, кроме появившегося move_iterator(ну ему это не особо и надо :)))
                      • basic_streambuf, basic_iostream, etc.
                      • все новые фичи сразу обзаводятся семантикой перемещения(tuple, к примеру).




                      <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

                      ExpandedWrap disabled
                        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 в стандартной библиотеке

                      Как уже было упомянуто, в библиотеке появилось следующее:
                      ExpandedWrap disabled
                        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++"
                      Сообщение отредактировано: archimed7592 -
                        Цитата archimed7592 @
                        блин, как будет proposal по русски? :)

                        Предложение
                        Цитата archimed7592 @
                        UTF-16 в большинстве случаев представляет одну букву одним символом, а суррогаты(в случае их неправильной интерпретации) могут повредить только одну букву(рядом с которой они находятся).
                        UTF-32 во всех случаях представляет одну букву одним символом.

                        :no: В 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'ов, которые позволят создать новый тип, который ведет себя точно так же, как и какой-то другой, но между ними не будет неявного преобразования. Полезно, например, когда какой-то примитивный тип по всем свойствам подходит для описания чего-либо (например, координаты или физические величины или хэндлы объектов ОС), но неявные преобразования нежелательны.
                        Пример:
                        ExpandedWrap disabled
                          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
                          Цитата archimed7592 @
                          prohibited:

                          Ура. Очень разд этой виче.
                          Только не понял.. (может не очень внимательно читал...?)
                          ссылка на ссылку как..? Опять запрещена? ведь T&& это rValue reference а не ссылка на ссылку.. ((

                          Добавлено
                          Цитата LuckLess @
                          T&& это rValue reference

                          вообще имхо не лучшее обозначение. лучшеб там.. ну хотябы T^ rvalueRef;
                            Цитата archimed7592 @
                            implicitly инстанцирований, если не ошибаюсь.

                            Не понимаю, к чему ты клонишь. Кстати, выбором типа проблема не ограничивается. Например, тебе нужно сделать swap для объектов двух неизвестных типов. Какие тут могут быть варианты? Кто-то может реализовать у своего класса метод с именем swap, кто-то другой – с именем Swap, ещё кто-то может вообще такой метод не реализовывать, тогда остаётся только вызвать std::swap. Вот примерная реализация функции, вызывающей нужный swap, которая могла бы получиться со static if:

                            ExpandedWrap disabled
                              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);
                              }

                            Насколько всё лаконично, просто и понятно. А теперь сравни вот с этим извращением

                            ExpandedWrap disabled
                              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? :wacko:
                              Цитата Unreal Man @
                              Кто-то может реализовать у своего класса метод с именем swap, кто-то другой – с именем Swap, ещё кто-то может вообще такой метод не реализовывать

                              Это к психиатру, однозначно. Если есть соглашения, им нужно следовать, если нет - их нужно принять. Если тип из 3-парти либы, к нему нужно написать адаптер, который реализует соглашения.

                              Добавлено
                              а если найдутся умники которые реализуют методы sWap, svap, SWaP, pomenyat_mestami, и.т.д. Ты их тоже в статик иф засунешь??? :wall: Бред!
                                Цитата LuckLess @
                                ссылка на ссылку как..? Опять запрещена?
                                когда-то была разрешена? :unsure:

                                Цитата LuckLess @
                                ведь T&& это rValue reference а не ссылка на ссылку.. ((

                                ты наверное не понял, что && - интерпретируется как отдельный токен т.е.
                                ExpandedWrap disabled
                                  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 тоже разрабатывался комитетом.
                                0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
                                0 пользователей:
                                Страницы: (77) 1 [2] 3 4 ...  76 77


                                Рейтинг@Mail.ru
                                [ Script execution time: 0,0866 ]   [ 17 queries used ]   [ Generated: 19.03.24, 11:46 GMT ]