从函数返回带有值模板参数的类模板

时间:2013-07-12 15:58:07

标签: c++ templates function-templates class-template

假设我有一个简单的模板类:

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'\\')将不起作用,因为该函数需要返回一个类,该模板的模板不仅包含类型,还包含值。

如何从一个函数返回一个类模板,该函数不仅包含模板参数,还包含值模板参数?

2 个答案:

答案 0 :(得分:1)

您希望将运行时计算值转换为模板参数吗?这是不可能的。

答案 1 :(得分:1)

  

我只是在寻找一种省略wchar_t的方法,并在实例化过程中使用自动类型推导。

我可以想象出这样的情况:

  1. 仅在运行时已知的参数类型(您对它一无所知):您无法使用模板处理它:您需要重新设计代码并使用继承和虚函数(或者,可能,混合两者,模板和继承)

  2. 在编译时已知的参数类型,在运行时已知的参数值:左在模板参数列表中的参数类型并传递参数 value < / em>到构造函数,然后,为了方便用户,使工厂函数推导出类型

    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. 在编译时你知道一个类型列表并希望它们的行为不同(例如有不同的默认值):从列表中为每个类型制作模板特化,然后,为用户方便,创建typedef

      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;
     }
    
  4. 在这种情况下,用户仍然可以实例化自己的专业化。该方法的示例是std::basic_string类。 此外,如果使类成员staticstatic const和整数类型只在成员列表中定义,您可以简化您的专业化:

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