Карта сайта Kansoftware
НОВОСТИУСЛУГИРЕШЕНИЯКОНТАКТЫ
Разработка программного обеспечения

Operators revisited

Boost , ,

Operators revisited

Каждый оператор C++ имеет специальный тип тега, связанный с ним. Например, оператор бинарных + имеет связанный с ним тип тега plus_op. Этот тег оператора используется для специализации:

  1. unary_operator
  2. binary_operator

классы шаблонов (см. unary_operator и binary_operator ниже). Специализации этих unary_operator и binary_operator являются фактическими рабочими лошадками, которые реализуют операции. Поведение каждого ленивого оператора зависит от специализации unary_operator и binary_operator.

Предустановленные специализации соответствуют каноническим правилам оператора, смоделированным поведением целых чисел и указателей:

  • Префикс + и ~ принимает постоянные аргументы и возвращает объект по стоимости.
  • Это! принимает постоянные аргументы и возвращает булев результат.
  • The & (адрес), * (отсылка) оба возвращают ссылку на объект.
  • Префикс ++ возвращает ссылку на свой изменчивый аргумент после его увеличения.
  • Postfix ++ возвращает изменчивый аргумент по значению, прежде чем он будет увеличен.
  • += и его семейство принимают изменяемый операнд правой стороны (rhs) и возвращают ссылку на операнд rhs.
  • Infix+ и его семейство принимают постоянные аргументы и возвращают объект по стоимости.
  • == и его семья принимают постоянные аргументы и возвращают булев результат.
  • Операторы & & и | | принимают постоянные аргументы и возвращают булевый результат и оценивают короткое замыкание, как ожидалось.

Special operators and extensibility

Конечно, при необходимости можно переопределить стандартное поведение оператора. Например, поведение std::cout не соответствует каноническому сдвигу левого оператора<< (т.е. rhs std::cout является изменчивой ссылкой). Странные шары, такие как этот, помещаются в special_ops.hpp. Там вы найдете специализации для различных классов, найденных в стандартном либе.

Библиотека должна быть расширяемой. Пользователи могут реализовать свои собственные специализации, чтобы позволить другим библиотекам быть адаптированными для оценки частичной функции. Позже в разделе "Взаимодействие (с приложениями, библиотеками и фреймворками)" обсуждение будет сосредоточено на взаимодействии и расширении фреймворка.

Operator tags

Каждый оператор C++ имеет соответствующий тип тега. Используется для специализации unary_operator и binary_operator (см. ниже). Тег также служит ленивым типом оператора, совместимым с композитом в качестве операции. Вот два примера тегов оператора:

Унарный пример:

    struct negative_op {
        template <typename T0>
        struct result {
            typedef typename unary_operator<negative_op, T0>
                ::result_type type;
        };
        template <typename T0>
        typename unary_operator<negative_op, T0>::result_type
        operator()(T0& _0) const
        { return unary_operator<negative_op, T0>::eval(_0); }
    };

Бинарный пример:

    struct plus_op {
        template <typename T0, typename T1>
        struct result {
            typedef typename binary_operator<plus_op, T0, T1>
                ::result_type type;
        };
        template <typename T0, typename T1>
        typename binary_operator<plus_op, T0, T1>::result_type
        operator()(T0& _0, T1& _1) const
        { return binary_operator<plus_op, T0, T1>::eval(_0, _1); }
    };

Обратите внимание, что это снова отличные примеры сложной операции. Этот стиль специализированной функции вездесущ в рамках. Посмотрим, как будут работать классы шаблонов unary_operatorи binary_operator.

Вот полный список тегов оператора:

    //  Unary operator tags
    struct negative_op;         struct positive_op;
    struct logical_not_op;      struct invert_op;
    struct reference_op;        struct dereference_op;
    struct pre_incr_op;         struct pre_decr_op;
    struct post_incr_op;        struct post_decr_op;
    //  Binary operator tags
    struct assign_op;           struct index_op;
    struct plus_assign_op;      struct minus_assign_op;
    struct times_assign_op;     struct divide_assign_op;    struct mod_assign_op;
    struct and_assign_op;       struct or_assign_op;        struct xor_assign_op;
    struct shift_l_assign_op;   struct shift_r_assign_op;
    struct plus_op;             struct minus_op;
    struct times_op;            struct divide_op;           struct mod_op;
    struct and_op;              struct or_op;               struct xor_op;
    struct shift_l_op;          struct shift_r_op;
    struct eq_op;               struct not_eq_op;
    struct lt_op;               struct lt_eq_op;
    struct gt_op;               struct gt_eq_op;
    struct logical_and_op;      struct logical_or_op;

unary_operator

Класс unary_operator реализует большинство унарных операторов C++. Каждая специализация в основном представляет собой простую статическую оценочную функцию плюс файл типа result_type, который определяет тип возврата оценочной функции.

TagT является одним из тегов унарного оператора, и T является типом данных (аргументом), участвующим в операции. Вот пример:

    template <typename T>
    struct unary_operator<negative_op, T> {
        typedef T const result_type;
        static result_type eval(T const& v)
        { return -v; }
    };

Этот пример является именно тем, на что ссылался первый пример, который мы видели в разделе по тегам операторов.

Только поведение встроенных типов C/C++ учитывается в специализациях, предоставляемых в operator.hpp. Для определяемых пользователем типов эти специализации могут по-прежнему использоваться при условии, что операторские перегрузки таких типов соответствуют стандартному поведению встроенных типов.

Отдельный файл special_ops.hpp реализует больше специализаций STL. Другие более специализированные реализации unary_operator могут быть определены клиентом для конкретных типов тегов/данных унарного оператора.

binary_operator

Класс binary_operator реализует большинство бинарных операторов C++. Каждая специализация в основном представляет собой простую статическую оценочную функцию плюс файл типа result_type, который определяет тип возврата оценочной функции.

TagT является одним из тегов двоичного оператора выше T0, а T1 - это типы данных (аргументов), участвующие в операции. Вот пример:

    template <typename T0, typename T1>
    struct binary_operator<plus_op, T0, T1> {
        typedef typename higher_rank<T0, T1>::type const result_type;
        static result_type eval(T0 const& lhs, T1 const& rhs)
        { return lhs + rhs; }
    };

Именно на этот пример ссылался второй пример, который мы видели в разделе о тегах операторов. higher_rank— тип компьютера. Посмотрим, как это будет работать в ближайшее время, простите за пересылку информации.

Только поведение встроенных типов C/C++ учитывается в специализациях, предоставляемых в operator.hpp. Для определяемых пользователем типов эти специализации могут по-прежнему использоваться при условии, что операторские перегрузки таких типов соответствуют стандартному поведению встроенных типов.

Отдельный файл special_ops.hpp реализует больше специализаций STL. Другие более специализированные реализации unary_operator могут быть определены клиентом для конкретных типов тегов/данных унарного оператора.

Все бинарные_операторы, кроме логических_and_op и логических_or_op, имеют статическую функцию, которая выполняет фактическую операцию. Логика_and_op и логическая_or_op d являются особенными, поскольку эти два оператора оцениваются по короткому замыканию.

Short Circuiting || and &&

The logical_and_op and logical_or_op are special due to the C/C++ short circuiting rule, i.e. a || b and a && b are short circuit evaluated. A forwarding operation cannot be used because all function arguments are evaluated before a function is called. logical_and_op and logical_or_op are specialized composites with implied operations.

rank

Класс ранга имеет статическое постоянное «значение», которое определяет абсолютный ранг типа. Rankиспользуется для выбора типа результата бинарных операторов, таких как +. Тип с более высоким рангом выигрывает и используется как тип возврата оператора. Тип, определяемый пользователем, имеет очень высокий рейтинг и всегда выигрывает по сравнению с типом, определенным пользователем. Если это нежелательно, можно написать ранг специализации по типу. Вот некоторые предопределенные примеры:

    template <> struct rank<char>           { static int const value = 20; };
    template <> struct rank<signed char>    { static int const value = 20; };
    template <> struct rank<unsigned char>  { static int const value = 30; };
    template <> struct rank<wchar_t>        { static int const value = 40; };

Обратите внимание, что рейтинги 0..9999 зарезервированы фреймворком.

Компьютер типа шаблона higher_rankвыбирает тип (T0 или T1) с более высоким рангом. Мы видели в двоичном операторе plus_op, как он использовался. В частности:

    higher_rank<T0, T1>::type

Т0 или Т1 возвращается в зависимости от того, кто имеет более высокий ранг. В некоторых операторских приложениях, таких как a + b, результатом является тот, который имеет более высокий рейтинг. Например, если a имеет тип int, а b имеет тип double, результат будет иметь тип double. Это средство также может быть весьма полезным для оценки некоторых функций. Например, если у нас есть функция сумма (a, b, c, d, e), мы можем вызвать этот тип компьютера, чтобы получить тип с самым высоким рангом:

    higher_rank<TA,
        higher_rank<TB,
            higher_rank<TC,
                higher_rank<TD, TE>::type
            >::type
        >::type
    >::type
When used within templates, be sure to use 'typename' appropriately. See binary_operator<plus_op, T0, T1> above.


Статья Operators revisited раздела может быть полезна для разработчиков на c++ и boost.




Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.



:: Главная :: ::


реклама


©KANSoftWare (разработка программного обеспечения, создание программ, создание интерактивных сайтов), 2007
Top.Mail.Ru

Время компиляции файла: 2024-08-30 11:47:00
2025-09-16 13:11:38/0.0049479007720947/0