Проверьте, содержит ли пакет параметра тип

Я задавался вопросом, обеспечивает ли C++ 0x какие-либо встроенные возможности проверить, содержит ли пакет параметра шаблона variadic определенный тип. Сегодня, повысьте::: mpl:: содержит может использоваться для выполнения этого, если Вы используете повышение:: mpl:: вектор вместо надлежащих шаблонов variadic. Однако это имеет серьезное время компиляции наверху. Я предполагаю, C++ 0x имеет поддержку уровня компилятора станд.:: is_same. Таким образом, я думал, поддерживается ли обобщение как ниже также в компиляторе.

template <typename... Args, typename What>
struct is_present
{
  enum { value = (What in Args...)? 1 : 0 };
};
7
задан plasmacel 13 November 2019 в 09:37
поделиться

2 ответа

Нет, вы должны использовать (частичную) специализацию с вариационными шаблонами, чтобы делать вычисления времени компиляции, такие как это:

#include <type_traits>

template < typename Tp, typename... List >
struct contains : std::true_type {};

template < typename Tp, typename Head, typename... Rest >
struct contains<Tp, Head, Rest...>
: std::conditional< std::is_same<Tp, Head>::value,
    std::true_type,
    contains<Tp, Rest...>
>::type {};

template < typename Tp >
struct contains<Tp> : std::false_type {};

Существует только одна другая внутренняя операция для вариационных шаблонов, и это специальное Форма оператора Sazeof, который вычисляет длину списка параметров, например:

template < typename... Types >
struct typelist_len
{
   const static size_t value = sizeof...(Types);
};

, где вы получаете «У него есть серьезные компиляционные накладные расходы» с Boost MPL от? Я надеюсь, что вы не просто делаете предположения здесь. Boost MPL использует такие методы, как ленивый шаблон, чтобы попытаться уменьшить время компиляции, а не взорванию, как наивный шаблон Meta-программирование.

4
ответ дан 7 December 2019 в 03:15
поделиться

Если вы хотите избежать рекурсиона ручного типа, STD :: Common_Type , по-видимому, является единственной утилитой в STL, который является вариационным шаблоном, и Следовательно, единственный, который мог бы потенциально инкапсулировать рекурсию.


Решение 1

STD :: Common_Type находит наименее полученный тип в наборе типов. Если мы определим числа с типами, специально высокими числами с менее полученными типами, он находит наибольшее количество в наборе. Затем мы должны сопоставить равенство к ключевому типу на уровень вывода.

using namespace std;

struct base_one { enum { value = 1 }; };
struct derived_zero : base_one { enum { value = 0 }; };

template< typename A, typename B >
struct type_equal {
 typedef derived_zero type;
};

template< typename A >
struct type_equal< A, A > {
 typedef base_one type;
};

template< typename Key, typename ... Types >
struct pack_any {
 enum { value =
     common_type< typename type_equal< Key, Types >::type ... >::type::value };
};


Решение 2

Мы можем взломать common_type немного больше. Стандарт говорит

Программа может специализироваться на этой черте, если по крайней мере один параметр шаблона в Специализация - это пользовательский тип.

И описывает именно то, что находится внутри: рекурсивный случай частичной специализации, случай, который применяет двоичный оператор и терминал. По сути, это общий Fold функция , и вы можете добавить любой двоичной операции, которую вы будете. Здесь я использовал дополнение, потому что это более информативно, чем. Обратите внимание, что IS_Same возвращает Integral_Constant .

template< typename Addend >
struct type_sum { // need to define a dummy type to turn common_type into a sum
    typedef Addend type;
};

namespace std { // allowed to specialize this particular template
template< typename LHS, typename RHS >
struct common_type< type_sum< LHS >, type_sum< RHS > > {
    typedef type_sum< integral_constant< int,
     LHS::type::value + RHS::type::value > > type; // <= addition here
};
}

template< typename Key, typename ... Types >
struct pack_count : integral_constant< int,
 common_type< type_sum< is_same< Key, Types > > ... >::type::type::value > {};
2
ответ дан 7 December 2019 в 03:15
поделиться
Другие вопросы по тегам:

Похожие вопросы: