我如何使C++朋友模板专业化工作



我有一个类重载了位移位运算符,如下所示:

template<typename DataType>
friend Packet& operator << (Packet& pkt, const DataType& data)
{
std::cout << "this compiles" << std::endl;
}

但当我试图将其专业化时:

template<typename DataType>
friend Packet& operator << (Packet& pkt, const DataType& data)
{
std::cout << "this doesn't compile" << std::endl;
}
template<>
friend Packet& operator<<<std::string> (Packet& pkt, const std::string& data)
{
std::cout << "this doesn't compile" << std::endl;
}

它抛出一个编译时错误:

Error   C2116   'operator <<': function parameter lists do not match between declarations 

我在这里做错了什么?

如果我理解正确,下面是您想要实现的目标,对吗?


#include <iostream>
class Packet
{
public:
template<class T>
friend Packet& operator << (Packet& pkt, const T& data);
};
template<class DataType>
Packet& operator << (Packet& pkt, const DataType& data)
{
std::cout << "primary" << std::endl;
return pkt; // handle it as as per your logic
}
template<>
Packet& operator<< (Packet& pkt, const std::string& data)
{
std::cout << "specialisation for std::string" << std::endl;
return pkt; // handle it as as per your logic
}
int main()
{

Packet p1;
p1<<4;
p1<<std::string("samplestring");
return 0;
}

如何使C++朋友模板专业化工作?

好友模板只能声明主模板和主模板的成员。与主模板相关联的任何部分专业化和显式专业化也被自动视为朋友。

因此,为了解决代码中的问题,您可以在类Packet中为主模板添加友元模板声明,然后定义该主模板以及类外的任何其他专用化,如下所示:

#include <iostream>
#include<string>
struct Packet
{
//friend template declaration for primary template 
template<typename DataType>
friend Packet& operator << (Packet& pkt, const DataType& data);
};
//implementation of primary template
template<typename DataType>
Packet& operator << (Packet& pkt, const DataType& data)
{
std::cout << "primary template called" << std::endl;
return pkt;
}
//implementation of explicit specialization
template<>
Packet& operator<<<std::string> (Packet& pkt, const std::string& data)
{
std::cout << "specialization for std::string called" << std::endl;
return pkt;
}
int main()
{
Packet p;
p << 100; //uses primary template

std::string s("someString");
p << s; //uses specialization for std::string
return 0;
}

工作演示。

我所做的改变包括:

  1. Packet内的主模板添加了一个朋友模板声明
  2. 添加了主模板的实现以及类Packet之外的显式专门化。请注意,在类外的实现中不需要friend关键字。此外,显式专门化自动成为Packet的友元,因此不需要在类Packet中为该专门化有友元声明
  3. 添加了原始示例问题中缺少的返回语句

最新更新