Могут ли параметры шаблона соответствовать обоим типам и шаблонам без проблем, возможно, как часть вариаций? - PullRequest
0 голосов
/ 12 января 2019

Мой код хранит некоторые состояния, используя конструкцию статического типа, аналогичную конструкции в Boost.PolyCollection.

Моя проблема, я думаю, минимально проиллюстрирована приведенным ниже кодом. По сути, я работаю с пакетами параметров и мне нужен способ «создать экземпляр» данного шаблона в соответствии с тем, что находится в пакете.

#include <unordered_map>

template<typename... Ts>
struct Pack
{
    /*
    instantiate a given template with passed types + the types in this Pack
        but passed Template may take non-type template parameters, what to do??
    */
    // template<template<typename...> class Template, typename... As> // error: type/value mismatch at argument 1 in template parameter list for 'template<class ... Ts> template<template<template<class ...> class Template, class ... As> template<class ... Ts> template<class ...> class Template, class ... As> using Inst = Template<As ..., Ts ...>'
    // using Inst = Template<As..., Ts...>;


    // this works for my case, but it's too specific and ugly -
        // am fixing the first of As to be a non-type 
    template<template<template<typename...> class, typename...> class Template, template<typename...> class A1, typename... As>
    using Inst = Template<A1, As..., Ts...>;
};

template<template<typename...> class Segment, typename Key, typename... Ts>
class AnyMap
{
};

int main()
{
    typedef Pack<int, char> ServicePack;
    typedef long Key;

    using ServiceMap = typename ServicePack::template Inst<AnyMap, std::unordered_map, Key>; // AnyMap with given segment type and key
}

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

Знаете ли вы о простом способе достижения этого?

(возможно, очевидно, речь идет о c ++ 17)

1 Ответ

0 голосов
/ 12 января 2019

Есть два связанных подхода.

Во-первых, это стиль буст-хана. Превратите все в значения времени компиляции. Шаблоны? Ценность. Типы? Ценность. Ценности? Экземпляр типа, подобного интегральной константе.

Метапрограммирование теперь является программированием constexpr.

Второй подход - превратить все в типы.

Сюда входят нестандартные параметры шаблонов шаблонов.

template<claas T, class N>
using array=std::array<T,N{}()>;

template<auto x>
using k=std::integral_constant<decltype(x), x>;

теперь мы можем передать k<77> как тип, представляющий параметр шаблона нетипичного типа 77 в array<int,k<77>> и получить std::array<int,77>.

Шаблон массива только для типа теперь легко метапрограммировать. Просто запишите эти обертки и удалите метапрограмму.

Передача шаблонов может быть:

template<template<class...>class> struct Z{};

теперь мы можем передать Z<array> как тип.

...