На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
Модераторы: Qraizer, Hsilgos
Страницы: (78) « Первая ... 24 25 [26] 27 28 ...  77 78  ( Перейти к последнему сообщению )  
> Текущий Стандарт С++ и перспективы его развития
    Цитата Masterkent @
    но комитет просто не видит в этом достаточной выгоды, чтобы переписывать правила.

    Странно (на мой взгляд). Достаточно взглянуть на приведенный пример. Ведь это просто следующий шаг (после лямбд и инстанцирования локальными типами). in-place-полиморфные врапперы, избавляющие кодера от, гм..., ненужных шаманств. Другой пример (по идее, должен компилироваться):

    ExpandedWrap disabled
      class Foo
      {
      public:
         typedef boost::variant<int, std::string, double> var_type;
       
         void Process(var_type const& v)
         {
            struct Processor : boost::static_visitor<>
            {
               Foo* m_Object;
               Processor(Foo* obj) : m_Object(obj) {;}
               template<typename T> void operator()(T val) const {m_Object->Process(val);}
            } p(this);
            
            boost::apply_visitor(p, v);
         }
      private:
       
         void Process(int a);
         void Process(std::string a);
         void Process(double a);
      };

    Теперь прикинь, сколько тебе придется писать сейчас. А учитывая, что этот Processor можно завернуть в макрос:
    ExpandedWrap disabled
      #define DEF_VISITOR(cls, method) \
            struct Processor : boost::static_visitor<> \
            {   \
               cls* m_Object;   \
               Processor(cls* obj) : m_Object(obj) {;}  \
               template<typename T> void operator()(T val) const {m_Object->Method(val);} \
            }

    с последующим использованием:
    ExpandedWrap disabled
      class Foo
      {
      public:
         typedef boost::variant<int, std::string, double> var_type;
       
         void Process(var_type const& v)
         {
            DEF_VISTOR(Foo, Process) p(this);
            
            boost::apply_visitor(p, v);
         }
      private:
       
         void Process(int a);
         void Process(std::string a);
         void Process(double a);
      };

    разница становится еще более очевидной.

    Добавлено
    Только что проверил (на полусобранном gcc 4.5) - локальный класс в теле метода класса имет полный доступ к private-потрохам класса. Что и требуется.
      Цитата Flex Ferrum @
      Ну, вообще говоря, по-моему, отсутствие имени у таких перечислений не мешало мне использовать их в качестве параметров шаблонов... У них ведь, вроде как (у констант, в смысле) получается тип int. Или я чего-то недопонимаю?
      Ну, значениями тебе никто не запрещал пользоваться, перечисления-то не требуют квалификации именем своего типа, т.к. они не создают областей видимости. Но ведь речь-то шла не о значениях, а о типе. Значение параметром в typename T не передашь.
      Проблема стала актуальной с появлением decltype и наделением auto новых возможностей. Их-то не запрещается использовать с безымянными типами.
        Flex Ferrum
        когда gcc 4.5 обещают?
        Сообщение отредактировано: Большой -
          Цитата Большой @
          когда gcc 4.5 обещают?

          Я ожидаю не раньше марта следующего года (судя по датам выходов предыдущих релизов). Сейчас четвертый день пытаюсь его из исходников под MinGW сбилдить... :wall: :wall: :wall: Вообщем, как только получится - выложу здесь. :)
            Цитата Flex Ferrum @
            Вообщем, как только получится - выложу здесь

            было бы очень хорошо
              Цитата Flex Ferrum @
              Теперь прикинь, сколько тебе придется писать сейчас.

              Можно сделать Processor закрытым членом Foo.

              Цитата Flex Ferrum @
              А учитывая, что этот Processor можно завернуть в макрос

              Тут, кстати, видна другая проблема: шаблонными аргументами нельзя передавать имена функций. Довольно неприятное ограничение. Указатели на функции-члены неудобны: ни с перегруженными функциями, ни с шаблонами функций, ни с функциями, имеющими аргументы по умолчанию, их зачастую нормально не поюзаешь. Иметь дело с именами функций было бы куда удобнее:

              ExpandedWrap disabled
                // подобное использование virtual, .(Fn) и .. - это просто мои допущения, в C++0x ничего такого нет.
                 
                template <virtual Fn, class C>
                    class MemFnBinder
                {
                public:
                    MemFnBinder(C const &x) :
                        m_obj(x) {}
                    template <class... Args>
                        auto operator ()(Args &&... args) const -> decltype(m_obj.(Fn)(args...))
                            { return m_obj.(Fn)(args...); }
                private:
                    C m_obj;
                };
                    
                template <virtual Fn, class C>
                    MemFnBinder<Fn, C> bind(C const &x)
                        { return MemFnBinder<Fn, C>(x); }
                    
                struct X
                {
                    void func(int, int = 0);
                };
                 
                void f()
                {
                    std::function<void (int)> fn1       = bind<..func>(X());
                    std::function<void (int, int)> fn2  = bind<..func>(X());
                }

              И, в частности, твой макрос можно было бы переписать примерно так:

              ExpandedWrap disabled
                template <class C, virtual Fn>
                    class Processor : boost::static_visitor<>
                {
                public:
                    Processor(C* obj) : m_object(obj) {}
                    template <class T>
                        void operator()(T val) const
                            { m_object->(Fn)(val); }
                private:
                    C* m_object;
                }

              причём, по-моему, не было бы никакого смысла делать такой шаблон локальным. Если он настолько обобщённый, что используется сразу в нескольких местах, то, наверное, ему самое место в пространстве имён. Локальным имело бы смысл делать код, который нигде больше, кроме как в данной функции, не используется - например:

              ExpandedWrap disabled
                template <class BidirectionalIterator>
                    void reverse(BidirectionalIterator first, BidirectionalIterator last)
                {
                    struct Aux
                    {
                        template <class BidirIt>
                            void operator()(BidirIt first, BidirIt last, std::bidirectional_iterator_tag)
                        {
                            for (; first != last && first != --last; ++first)
                                (swap)(*first, *last);
                        }
                 
                        template <class RanIt>
                            void operator ()(RanIt first, RanIt last, std::random_access_iterator_tag)
                        {
                            for (; first < last; ++first)
                                (swap)(*first, *--last);
                        }
                    };
                 
                    Aux()(first, last, typename std::iterator_traits<BidirectionalIterator>::iterator_category());
                }
              Сообщение отредактировано: Masterkent -
                Цитата Masterkent @
                причём, по-моему, не было бы никакого смысла делать такой шаблон локальным.

                В таком случае - да. Но... :huh:

                Цитата Masterkent @
                Можно сделать Processor закрытым членом Foo.

                Можно. Но это значит вносить изменения в интерфейс класса, что (в ряде случаев, да и вообще) некомильфо. А локальный класс (в данном случае) никуда, кроме функции (в которой объявлен) не "выглядывает".

                Цитата Masterkent @
                Тут, кстати, видна другая проблема: шаблонными аргументами нельзя передавать имена функций. Довольно неприятное ограничение.

                Угумс. Именно эту проблему и есть желание обойти. Указанным мною образом.
                  Цитата Flex Ferrum @
                  Но это значит вносить изменения в интерфейс класса

                  Публичного интерфейса класса это почти не касается, поэтому проблема второсортная, IMHO.
                    Цитата Masterkent @
                    Публичного интерфейса класса это почти не касается, поэтому проблема второсортная, IMHO.

                    Зато приведет к перекомпиляции зависимого от интерфейса кода. А это уже хуже.
                      Цитата Flex Ferrum @
                      Зато приведет к перекомпиляции зависимого от интерфейса кода.

                      Если эта проблема критична, то можно поместить данный вспомогательный класс в unnamed namespace.
                        Цитата Masterkent @
                        Если эта проблема критична, то можно поместить данный вспомогательный класс в unnamed namespace.

                        Да много чего можно то. :)
                          Цитата Flex Ferrum @
                          Да много чего можно то.

                          О том и речь: есть масса неплохих workaround-ов, так что оснований для пересмотра правил здесь может быть недостаточно.
                            Цитата Masterkent @
                            есть масса неплохих workaround-ов, так что оснований для пересмотра правил здесь может быть недостаточно.

                            Но удочку закинуть все равно можно.
                              Цитата Masterkent @
                              В смысле?

                              В смысле, поинтересоваться мнением общественности по этому поводу где-нибудь в comp.std.c++
                                Цитата mas912 @
                                Самое последнее, что я видел, это C++ Library Working Group Status Report (Post San Francisco 2008) (N2870

                                This project was cancelled by SC22 in September 2008 - на главной странице комитета. Весь TR2 отменили, кроме decimal floating point arithmetic.
                                0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
                                0 пользователей:
                                Страницы: (78) « Первая ... 24 25 [26] 27 28 ...  77 78


                                Рейтинг@Mail.ru
                                [ Script execution time: 0,0604 ]   [ 16 queries used ]   [ Generated: 20.06.25, 08:04 GMT ]