Заворачивание шаблона в другой шаблон - PullRequest
1 голос
/ 20 мая 2019

У меня есть пара объявлений шаблонов классов, таких как:

template<typename T, template<typename W> class X>
struct B {
    bool operator()(const T& left, const T& right)
    { return X<W>()(left, right); }
};

template<template<typename T> class X, typename Q>
struct A {
   bool operator()(const int a, const int b)
   {
      return B<Q, X>()(a, b);
   }
};

Я могу создать A<std::greater, int>, A<std::less, int>, и все работает, как я хочу.

Возможно лисоздать класс, который будет содержать шаблон, переданный как std::greater, и, тем не менее, его можно будет передавать как std::greater в приведенном выше примере?

Примерно так:

template <template <typename T> class Class>
class Wrapper
{
   operator()(const int, const int) { return Class<?what's here?> (value, value); }
};

Я хотел бы передать свой Wrapper неизменному A

A<Wrapper<std::less>, long>

Другими словами, я хочу имитировать шаблон, переданный моей обертке, для совместимости с реальной версией класса A.

1 Ответ

3 голосов
/ 20 мая 2019

Короткий ответ - нет, не совсем так, как вы этого хотите. Первый аргумент A должен быть именем шаблона. Но когда вы добавляете аргументы и пишете Wrapper<std::less>, вы получаете тип класса. Это больше не шаблон. Подумайте об этом так: A ожидает нож для печенья, но вместо этого вы передаете печенье, изготовленное из ножа.

Это не значит, что вы не можете превратить шаблон в другой шаблон, но он не будет таким непрозрачным. Решением является добавление шаблона member к Wrapper. Тогда Wrapper<std::less>, несмотря на то, что он является типом класса, будет иметь член, который является шаблоном. И вы можете передать это в A.

template <template <typename T> class Class>
struct Wrapper
{
   template<typename U> // member template
   struct temp {
     bool operator()(const int v1, const int v2)
     { return Class<U>()(v1, v2); }
   };
};

Это позволяет писать A<Wrapper<std::less>::temp, long>.

Проверьте это в прямом эфире .

...