简体   繁体   English

部分模板专业化 - 成员专业化

[英]Partial template specialization - member specialization

Say I have this template class: 说我有这个模板类:

template<typename T> class MyClass{
public:
    MyClass(const T& t):_t(t){}
    ~MyClass(){}
    void print(){ cout << _t << endl; }
private:
    T _t;
};

And I want to specialize it, so similarly I define: 我想专门研究它,所以同样我定义:

template<> class MyClass<double>{
    public:
        MyClass(const double& t):_t(t){}
        ~MyClass(){}
        void print(){ cout << _t << endl; }
    private:
        double _t;
};

Now, this is ok as long as we're talking about small classes. 现在,只要我们谈论小班,这是可以的。 If I have a very long class, it would be a lot smarter to specialize print() alone. 如果我有一个很长的课程,那么单独使用print()会更聪明。 I know how to do it with non-member function. 我知道如何使用非成员函数来完成它。 Is there any way to do it with member functions? 是否有任何方法可以使用成员函数?

One straightforward solution is, define base class template containing things which you want to specialize, and then specialize this class template instead (it would be a small class, after all): 一个简单的解决方案是,定义包含您想要专门化的东西的类模板,然后专门化这个类模板(毕竟它将是一个小类):

template<typename T> 
struct printable
{
 protected:
   void print(const T & _t)  { }
};

template<> 
struct printable<double>
{
 protected:
   void print(const double & _t)  { }
};

And then derived from it: 然后从中派生出来:

template<typename T> 
class MyClass : public printable<T>
{
   typedef printable<T> base;
public:
    MyClass(T t&):_t(t){}
    ~MyClass(){}
    void print(){ base::print(_t); } //forward
private:
    T _t;
};

You don't need to specialize this class template anymore; 您不再需要专门化这个类模板了; make it as huge as you want (and reasonable). 让它像你想要的那样巨大(而且合理)。


Another alternative is policy-based design in which you pass policy-class(es) as template argument(s) to your class template (called host class). 另一种替代方案是基于策略的设计 ,其中将策略类作为模板参数传递给类模板(称为主机类)。

For example, 例如,

//lets define few policy classes
struct cout_print_policy
{
    template<typename T>
    static void print(T const & data)
    {
       std::cout << "printing using cout = " << data << std::endl;
    }
};

struct printf_print_policy
{
    static void print(int data)
    {
       std::printf("printing int using printf = %d\n", data);
    }
    static void print(double data)
    {
       std::printf("printing double using printf = %f\n", data);
    }
};

//now define the class template (called host class) that 
//accepts policy as template argument
template<typename T, typename TPrintPolicy>
class host
{
    typedef TPrintPolicy print_policy;
    T data;
 public:
    host(T const & d) : data(d) {}
    void print() 
    {
        print_policy::print(data);
    }
};

Test code: 测试代码:

int main()
{
  host<int, cout_print_policy>      ic(100);
  host<double, cout_print_policy>   dc(100.0);

  host<int, printf_print_policy>    ip(100);
  host<double, printf_print_policy> dp(100.0);

  ic.print();
  dc.print();
  ip.print();
  dp.print();
}

Output: 输出:

printing using cout = 100
printing using cout = 100
printing int using printf = 100
printing double using printf = 100.000000

Online demo : http://ideone.com/r4Zk4 在线演示: http//ideone.com/r4Zk4

In your example, you are using full specialization. 在您的示例中,您使用的是完全专业化。 In that case, you can do it like this: 在这种情况下,你可以这样做:

template <>
void MyClass<double>::print()
{
  cout << _t << endl;
}

but it doesn't work for partial specialization. 但它不适用于部分专业化。

You can specialize your print member function specially for double: 您可以专门为双重打印成员功能:


template< typename T >
class MyClass{
public:
       MyClass(T t&):_t(t){}
    ~MyClass(){}
    void print(){}
private:
    T _t;
};
template< typename T >
void MyClass< T >::print(){/* your specific implementation*/}

template<>
void MyClass< double >::print(){/* your specific implementation*/}

in class.h 在class.h中

// declaration of template class
template<typename T>
class MyClass
{
public:
    MyClass(T t&):_t(t){}
    ~MyClass(){}
    void print();    // general "declaration". 
                     // don't use inline definition for these case
private:
    T _t;
};

// specialization "declaration" of wanted member function
template<>
void MyClass<double>::print();

#include "class.inl" // implementation of template class

in class.inl 在class.inl

// general "definition" of wanted member function
template<typename T>
void MyClass<T>::print()
{
    cout << _t << endl;
}

in class.cpp 在class.cpp中

#include "class.h"

// specialization "definition" of wanted member function
// specialization definition of anyone must be here.. not inl file..
void MyClass<double>::print()
{
    cout << "double specialization " << _t << endl;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM