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

common_type

Boost , Chapter 1. Boost.TypeTraits , Alphabetical Reference

Boost C++ Libraries

...one of the most highly regarded and expertly designed C++ library projects in the world. Herb Sutter and Andrei Alexandrescu, C++ Coding Standards

PrevUpHomeNext

Заголовок:или<#include<boost/type_traits.hpp>>

namespace boost {
  template <class... T> struct common_type;
}

<common_type>является классом признаков, используемым для вывода типа, общего для нескольких типов, полезного в качестве возвращаемого типа функций, работающих на нескольких типах ввода, таких как арифметика смешанного режима.

Вложенный типдеф<::type>можно определить следующим образом:

template <class... T>
struct common_type;
template <class T, class U, class... V>
struct common_type<T, U, V...> {
    typedef typename common_type<typename common_type<T, U>::type, V...>::type type;
};
template <>
struct common_type<> {
};
template <class T>
struct common_type<T> {
    typedef typename decay<T>::type type;
};
template <class T, class U>
struct common_type<T, U> {
    typedef typename decay<
        decltype( declval<bool>()?
            declval<typename decay<T>::type>():
            declval<typename decay<U>::type>() )
    >::type type;
};

Все типы параметров должны быть полными. Эта черта может быть специализирована пользователем, если по крайней мере один параметр шаблона является типом, определенным пользователем.Примечание:Такие специализации необходимы, когда среди аргументов<common_type>требуются только явные преобразования.

Обратите внимание, что когда компилятор не поддерживает вариадные шаблоны (и определяется макрос<BOOST_NO_CXX11_VARIADIC_TEMPLATES>), то максимальное количество аргументов шаблона составляет 9.

Tutorial

В двух словах,<common_type>является чертой, которая принимает 1 или более типов и возвращает тип, который все типы преобразуют. Определение по умолчанию требует, чтобы это преобразование было неявным. Однако эта черта может быть специализирована для определенных пользователем типов, которые хотят ограничить свои межтиповые конверсии явными и все же хотят взаимодействовать с объектом<common_type>.

Пример:

template <class T, class U>
complex<typename common_type<T, U>::type>
operator+(complex<T>, complex<U>);

В приведенном выше примере допускается комплексная арифметика «смешанного режима». Тип возврата описывается<common_type>. Например, полученный тип добавления<complex<float>>и<complex<double>>может быть<complex<double>>.

Вот как кто-то может создать вариадную функцию сравнения:

template <class ...T>
typename common_type<T...>::type
min(T... t);

Это очень полезная и широко применимая утилита.

How to get the common type of types with explicit conversions?

Другим вариантом для автора предыдущего оператора может быть

template <class T, class U>
typename common_type<complex<T>, complex<U> >::type
operator+(complex<T>, complex<U>);

Поскольку определение по умолчанию<common_type>требует, чтобы преобразование было неявным, мы должны специализировать черту для сложных типов следующим образом.

template <class T, class U>
struct common_type<complex<T>, complex<U> > {
    typedef complex< common_type<T, U> > type;
};
How important is the order of the common_type<> template arguments?

Порядок параметров шаблона важен.

<common_type<A,B,C>::type>не является эквивалентом<common_type<C,A,B>::type>, но<common_type<common_type<A,B>::type,C>::type>.

рассмотреть

struct A {};
struct B {};
struct C {
    C() {}
    C(A const&) {}
    C(B const&) {}
    C& operator=(C const&) {
        return *this;
    }
};

Следующее не компилируется

typedef boost::common_type<A, B, C>::type ABC; // Does not compile

пока

typedef boost::common_type<C, A, B>::type ABC;

компиляции.

Так как<common_type<A,B>::type>не определено,<common_type<A,B,C>::type>также не определено.

Предполагается, что клиенты, которые хотят, чтобы<common_type<A, B>>были четко определены, чтобы определить его сами:

namespace boost
{
template <>
struct common_type<A, B> {typedef C type;};
}

Теперь этот клиент может попросить<common_type<A, B,C>>(и получить тот же ответ).

Клиенты, желающие запросить<common_type<A, B,C>>в любом порядке и получить тот же результат, должны добавить дополнительно:

namespace boost
{
template <> struct common_type<B, A>
: public common_type<A, B> {};
}

Это необходимо, так как специализация<common_type<A, B>>не используется неявно для<common_type<B, A>>.

Can the common_type of two types be a third type?

Учитывая предыдущий пример, можно ожидать, что<common_type<A,B>::type>будет<C>без какого-либо вмешательства со стороны пользователя. Но реализация<common_type<>>по умолчанию этого не допускает. Предполагается, что клиенты, желающие, чтобы<common_type<A, B>>было четко определено, чтобы определить его сами:

namespace boost
{
template <>
struct common_type<A, B> {typedef C type;};
template <> struct common_type<B, A>
: public common_type<A, B> {};
}

Теперь этот клиент может попросить<common_type<A, B>>.

How does common_type behave with pointers?

рассмотреть

struct C { }:
struct B : C { };
struct A : C { };

Не должно ли быть<common_type<A*,B*>::type><C*>? Я бы сказал, что да, но реализация по умолчанию сделает его плохо сформированным.

Библиотека могла бы добавить специализацию для указателей, как

namespace boost
{
    template <typename A, typename B>
    struct common_type<A*, B*> {
        typedef common_type<A, B>* type;
    };
}

Но в отсутствие мотивирующих вариантов использования мы предпочитаем не добавлять больше, чем указано в стандарте.

Конечно, пользователь всегда может сделать эту специализацию.

Can you explain the pros/cons of common_type against Boost.Typeof?

Даже если они кажутся близкими,<common_type>и<typeof>имеют разные цели. Вы используете<typeof>, чтобы получить тип выражения, в то время как вы используете<common_type>, чтобы явно установить тип возвращаемой функции шаблона. Оба являются взаимодополняющими, и действительно<common_type>приблизительно эквивалентны<decltype(declval<bool>() ?declval<T>() :declval<U>())>.

<common_type>также аналогично<promote_args<class...T>>в<boost/math/tools/promotion.hpp>, хотя это не совсем то же самое, что<promote_args>.<common_type<T1,T2>::type>просто представляет собой результат некоторой операции на<T1>и<T2>и по умолчанию для типа, полученного путем вставки<T1>и<T2>в условное утверждение.

Он должен быть настраиваемым (через специализацию), если этот по умолчанию не подходит.


PrevUpHomeNext

Статья common_type раздела Chapter 1. Boost.TypeTraits Alphabetical Reference может быть полезна для разработчиков на c++ и boost.




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



:: Главная :: Alphabetical Reference ::


реклама


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

Время компиляции файла: 2024-08-30 11:47:00
2025-05-20 03:14:26/0.0029270648956299/0