2013-07-12 2 views
0

Предположим, у меня есть простой класс шаблона:Возвращает шаблон класса с аргументами шаблона значения из функции

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'\\') не будет работать, потому что функция должна возвращать класс, шаблон содержит не только тип, но и значение.

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

+1

Шаблоны времени компилирования животные. Если вы используете разные значения 'Element' во время выполнения, можете ли вы просто сделать параметр Element' конструктором? – Drop

+0

Статические типы в порядке в моем случае, я просто ищу способ опустить 'wchar_t' и использовать автоматический вывод типа во время создания экземпляра. Думаю, это просто невозможно. –

ответ

0

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

+0

Возможно ли подобное с C++ 11 'constexpr'? –

+0

Основная проблема заключается в том, что вы не можете превратить вычисляемое значение времени выполнения в новый тип (если вы изменяете параметр шаблона, вы определяете новый тип). –

1

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

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

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

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

    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. Во время компиляции вы знаете, список типов и хочет они ведут себя по-разному (например, имеют различные значения по умолчанию): сделать специализации шаблонов для каждого типа из списка, то для удобства пользователя, создать

    определения типов
    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'; 
}; 
Смежные вопросы