我有一个具有两个不同功能的模板类(OutgoingPacket):
void _prepare() {
assert(false); // this should have been specialized and the native function never called.
}
template <typename Args, typename ... RemArgs>
void _prepare(Args&& args, RemArgs&& ... remArgs) {
assert(false); // this should have been specialized and the native function never called.
}
然后,我在类定义之外定义了两者的一些特化:
// no args
template <> void OutgoingPacket<PacketServerAck> ::_prepare();
template <> void OutgoingPacket<PacketSup> ::_prepare();
template <> void OutgoingPacket<PacketWelcome> ::_prepare();
template <> void OutgoingPacket<PacketServerPing>::_prepare();
// with args
template <> template <> void OutgoingPacket<PacketGTFO>::_prepare<std::string>(std::string&& message);
template <> template <> void OutgoingPacket<PacketPlayer>::_prepare<std::shared_ptr<User>>(std::shared_ptr<User>&& user);
不带参数的函数调用prepare按预期工作,但调用带参数的重载调用基本模板;他们触发断言。
为什么会这样?
更新:我刚刚尝试修改专业化定义以包含具有相同结果的引用:
template <> template <> void OutgoingPacket<PacketGTFO>::_prepare<std::string&&>(std::string&& message);
template <> template <> void OutgoingPacket<PacketPlayer>::_prepare<std::shared_ptr<User>&&>(std::shared_ptr<User>&& user);
附带说明一下,我这样做的原因是因为我不认为基类 OutgoingPacket 应该散布所有这些不同版本的准备函数。而且我觉得子类化不合适,因为不同 OutgoingPackets 之间的差异非常小(约 4 行)。
本质上,OutgoingPacket 对象是使用任意参数创建的,然后将其转发给准备函数:
template<typename ... Args>
OutgoingPacket(Args&&... args) {
_prepare(std::forward<Args>(args)...);
}
如果这是不好的做法,我可以得到一些关于设计的建议吗?