模板专业化

时间:2011-04-04 19:40:52

标签: c++

template<class T> struct ISocket
{
    void connect(){}
    void raw_socket(){}
};

template <class SocketType, class Arg1,class Arg2>
struct ISocket< SocketType(Arg1,Arg2) > 
{
    typedef SocketType socket_type;
    typedef Arg1 arg_type;
    typedef Arg2 arg_type2;

    socket_type* raw_socket_;

    ISocket():raw_socket_(&SocketType()){}


    socket_type& raw_socket(){return *raw_socket_;}


    void connect()
    {
        raw_socket_->connect();
    } 
};

为什么我有义务定义模板结构ISocket; ?当您尝试使用ISocket并调用connect for instance

时,下面的代码不能在VS2010下编译
template<class T> struct ISocket;

template <class SocketType, class Arg1,class Arg2>
struct ISocket< SocketType(Arg1,Arg2) > 
{
    typedef SocketType socket_type;
    typedef Arg1 arg_type;
    typedef Arg2 arg_type2;

    socket_type* raw_socket_;

    ISocket():raw_socket_(&SocketType()){}


    socket_type& raw_socket(){return *raw_socket_;}


    void connect()
    {
        ref_raw_socket_->connect();
    } 
};

我用这段代码打电话:

struct SocketTcp
{
    void setup(std::string ip,int port)
    {
        std::cout << ip.c_str() << " " << port << "\n";
    }

    void connect()
    {

    }
};


typedef ISocket< SocketTcp(std::string, int) > Socket;

int main()
{

    ISocket<Socket> s;

    s.connect();
    s.raw_socket(); 
}   

1 个答案:

答案 0 :(得分:2)

首先,ref_raw_socket_->connect();。您没有会员ref_raw_socket_,只有raw_socket_
其次,您将其初始化为临时 SocketType()。构造函数之后,该对象被销毁,不再存在,并且您的指针现在是悬空指针,如果您使用它,则它是未定义的行为。
第三,您期望作为ISocket的模板参数?
修改
这个ISocket<Socket> s;对你的typedef毫无意义。您使用ISocket作为ISocket的参数?如果我将呼叫站点更改为:

typedef ISocket< SocketTcp(std::string, int) > Socket;

int main(){
    Socket s;
//  ^^^^^^ not ISocket<Socket>

    s.connect();
    s.raw_socket(); 
}

将构造函数更改为this(并添加析构函数):

ISocket()
    : raw_socket_(new SocketType())
{}

~ISocket(){
    delete raw_socket_;
}

代码编译得很好,没有错误。为什么我使用new,请在编辑前查看我的第二点。