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

发布于 2024-12-06 17:02:15 字数 591 浏览 0 评论 0原文

假设我有这个模板类:

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

我想专门化它,所以类似地我定义:

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

现在,只要我们谈论小类,就可以了。如果我的课程很长,那么单独专门化 print() 会更明智。我知道如何使用非成员函数来做到这一点。有没有办法用成员函数来做到这一点?

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. I know how to do it with non-member function. Is there any way to do it with member functions?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

早乙女 2024-12-13 17:02:15

在您的示例中,您正在使用完全专业化。在这种情况下,您可以这样做:

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

但它不适用于部分专业化。

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.

写给空气的情书 2024-12-13 17:02:15

化这个类模板(毕竟,它将是一个小类):

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

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

然后从中派生:

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;
};

一个简单的解决方案是,定义包含您想要专门化的内容的类模板,然后专门 不再需要专门化这个类模板;让它像你想要的那样大(并且合理)。


另一种选择是基于策略的设计,其中您将策略类作为模板传递类模板的参数(称为主机类)。

例如,

//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);
    }
};

测试代码:

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();
}

输出:

使用 cout = 100 打印
使用 cout = 100 打印
使用 printf = 100 打印 int
使用 printf = 100.000000 打印双精度

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

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

初相遇 2024-12-13 17:02:15

您可以专门为双精度打印成员函数:

<代码>

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*/}


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*/}

ζ澈沫 2024-12-13 17:02:15

在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

在class.inl中

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

在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;
}

in 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

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

in 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;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文