Вернуть шаблон класса с аргументами шаблона значения из функции

Предположим, у меня есть простой шаблонный класс:

template <typename ElementType, ElementType Element>
class ConsecutiveMatcher
{
public:
bool operator () (ElementType lhs, ElementType rhs)
{
return lhs == Element && rhs == Element;
}
};

Я обычно делаю создание экземпляров проще, чем ConsecutiveMatcher<wchar_t, L'\\'>() предоставляя функцию, которая может выводить типы аргументов шаблона на основе типов параметров:

template <typename ElementType>
ConsecutiveMatcher<ElementType, Element /* ?? */>
MakeConsMatcher(ElementType Element)
{
return ConsecutiveMatcher<ElementType, Element>();
}

Однако в этом случае MakeConsMatcher(L'\\') не будет работать, потому что функция должна возвращать класс, шаблон которого содержит не только тип, но и значение.

Как я могу вернуть шаблон класса из функции, которая имеет не только аргументы шаблона типа, но и аргументы шаблона значения?

0

Решение

Вы хотите, чтобы вычисленное значение во время выполнения превратилось в аргумент шаблона? это невозможно.

1

Другие решения

Я просто ищу способ пропустить wchar_t и использовать автоматическое удержание типа во время создания экземпляра.

Я могу представить себе такие ситуации:

  1. Тип аргумента известен только во время выполнения (и вы не имеете никакого представления об этом): вы не можете обрабатывать его с помощью шаблонов: вы захотите изменить дизайн своего кода и использовать наследование и виртуальные функции (или, возможно, смешать оба, шаблоны и наследование)

  2. Тип аргумента, известный во время компиляции, значение аргумента, известное во время выполнения: оставил Тип аргумента в списке аргументов шаблона и передать аргумент значение конструктор, затем, для удобства пользователя, сделать функцию фабрики для вывода типа

    template<typename T>
    struct MyType
    {
    template <class T>
    MyType(const T& defaultValue) :
    value(defaultValue)
    {}
    T value;
    };
    
    template<typename T>
    MyType<T> MyFactory(const T& defaultValue)
    {
    return MyType<T>(defaultValue);
    }
    
    int main()
    {
    char c = 'a';
    wchar_t w = L'a';
    int i = 42;
    float f = 3.14f;
    
    auto mt_char = MyFactory(c);
    auto mt_wchar = MyFactory(w);
    auto mt_int = MyFactory(i);
    auto mt_float = MyFactory(f);
    }
    
  3. Во время компиляции вы знаете список типов и хотите, чтобы они вели себя по-разному. (например, имеют разные значения по умолчанию): создайте специализации шаблонов для каждого типа из списка, затем для удобства пользователя создайте typedefs

      template<typename T> struct MyType
    {
    MyType(const T& defaultValue) :
    value(defaultValue)
    {}
    
    T value;
    };
    
    template<>
    struct MyType <char>
    {
    MyType() :
    value('c')
    {}
    
    char value;
    };template<>
    struct MyType <wchar_t>
    {
    MyType() :
    value(L'w')
    {}
    
    wchar_t value;
    };
    
    typedef MyType<char> MyTypeChar;
    typedef MyType<wchar_t> MyTypeWchar;
    
    int main()
    {
    MyTypeChar mt_char_default;
    MyTypeWchar mt_wchar_default;
    }
    

В этом случае пользователь все еще может создавать свои собственные специализации. Примером такого подхода является std::basic_string учебный класс.
Кроме того, вы можете упростить свою специализацию, если сделать членов класса static или же static const а для целочисленных типов просто определите в списке членов:

template<>
struct MyType <char>
{
static const char value = 'c';
};
1

По вопросам рекламы [email protected]