是部分类模板专门化这个设计问题的答案吗? [英] Is partial class template specialization the answer to this design problem?

查看:143
本文介绍了是部分类模板专门化这个设计问题的答案吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设您有一个班级,他是要连接到远程服务器的工作。我想抽象这个类提供两个版本,一个通过UDP连接,另一个通过TCP连接。我想构建最精简的运行时代码可能,而不是使用多态性,我正在考虑模板。这是我想象的,但我不知道这是最好的方法这样做:

Say you have a class who's job it is to connect to a remote server. I want to abstract this class to provide two versions, one that connects through UDP and the other through TCP. I want to build the leanest runtime code possible and instead of using polymorphism I am considering templates. Here is what I'm envisioning but I'm not sure it's the best way of doing this:

class udp {};
class tcp {};

template<class T,typename X>
class service
{
private:
  // Make this private so this non specialized version can't be used
   service();
};

template<typename X>
class service<udp, X>
{
private:
   udp _udp;
   X _x;
};

template<typename X>
class service<tcp, X>
{
private:
   tcp _tcp;
   X _x;
};

所以最终的好处是T的通用性仍然可用,但是需要非常不同的代码设置UDP或TCP连接已专门化。我想你可以把它放在一个类,或提供另一个类,坚持一些纯虚拟接口设置网络连接,如IConnectionManager。

So the end benefit is that the genericness of T is still available, but the very different code required to setup a UDP or TCP connection has been specialized. I suppose you could put it both into one class, or provide another class that adheres to some pure virtual interface for setting up the network connection, like IConnectionManager.

但这留下通用T的代码的问题现在必须被写入和维持在两个专门的版本中,其中它们最终是相同的。如何最好地解决这个问题?

But this does leave the problem of the code for the generic T now having to be written in and maintained in both specialized versions, where they are ultimately the same. How best to address this? I have a feeling I am going about this all wrong.

推荐答案

这最好使用传输协议的策略:

This can be best done using a policy for the transport protocol:

template<typename Transport>
class service : Transport {
public:
    typedef Transport transport_type;

    // common code
    void do_something() { 
        this->send(....);
    }
};

class tcp {
public:
    void send(....) {

    }
};

class udp {
public:
    void send(....) {

    }
};

typedef service<tcp> service_tcp;
typedef service<udp> service_udp;

注意,这也是多态的。它被称为编译时多态性。将策略放入基类将受益于空基类优化。也就是说,你的基类不需要占用任何空间。将策略作为成员具有另一个缺点,您总是必须向该成员委派东西,这可能会随时间变得烦人。 Modern C ++ Design 这本书深入地描述了这种模式。

Note that this is also polymorphic. It's called compile time polymorphism. Putting the policy into a base class will benefit from the Empty-Base-Class-Optimization. That is, your base class does not need to take any space. Putting the policy as a member has the other drawback that you always have to delegate stuff to that member, which can become annoying with time. The book Modern C++ Design describes this pattern in-depth.

理想情况下,传输协议不需要知道任何关于它上面的协议。但是如果由于某种原因需要获取一些信息,可以使用crtp模式 wiki

Ideally, the transport protocol doesn't need to know anything about the protocol above it. But if for some reason you have to get some information about it, you can use the crtp pattern wiki:

template<template<typename Service> class Transport>
class service : Transport<service> {

    // since we derive privately, make the transport layer a friend of us, 
    // so that it can cast its this pointer down to us. 
    friend class Transport<service>;

public:
    typedef Transport<service> transport_type;

    // common code
    void do_something() { 
        this->send(....);
    }
};

template<typename Service>
class tcp {
public:
    void send(....) {

    }
};

template<typename Service>
class udp {
public:
    void send(....) {

    }
};

typedef service<tcp> service_tcp;
typedef service<udp> service_udp;

您不必将模板放入标题。如果明确实例化它们,您将获得更快的编译时间,因为必须包括更少的代码。将它放入service.cpp:

You don't have to put your templates into headers. If you explicitly instantiate them, you will gain faster compilation times, as much fewer code has to be included. Put this into service.cpp:

template class service<tcp>;
template class service<udp>;

现在,使用服务的代码不需要知道服务的模板代码,已经生成到service.cpp的目标文件中。

Now, code that uses service does not need to know about the template code of service, since that code is already generated into the object file of service.cpp.

这篇关于是部分类模板专门化这个设计问题的答案吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆