我有一个类重载了位移位运算符,如下所示:
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;
}
工作演示。
我所做的改变包括:
- 为
Packet
内的主模板添加了一个朋友模板声明 - 添加了主模板的实现以及类
Packet
之外的显式专门化。请注意,在类外的实现中不需要friend
关键字。此外,显式专门化自动成为Packet
的友元,因此不需要在类Packet
中为该专门化有友元声明 - 添加了原始示例问题中缺少的返回语句