C++模板类型参数X使X*推导为nullptr_t的实现是否可行?
问题解答
基础模板需求可行性
单纯找类型X使得a<X>::pointer_type严格等于std::nullptr_t是无法实现的。
原因是C++标准中,std::nullptr_t是独立的标量类型,定义为decltype(nullptr),它可以隐式转换为任意指针类型,但本身不属于任何T*类型的实例,没有任何类型T满足T*与std::nullptr_t是相同类型。
实际场景解决方案
你的真实需求是让HDRONLY实例可以接收nullptr作为消息参数,不需要严格要求MSG*等于nullptr_t,可以用以下几种方案实现:
方案1:使用void作为占位类型(最小改造成本)
直接将X设为void,同时调整encodeHdr、decodeHdr的签名,把对应消息参数的类型改为const void*和void*即可,不需要修改原有msgid模板定义:
int encodeHdr(const MsgHeader* pHeader, const void* pMessage, unsigned char* destBuf, int destBufSize) { // 逻辑中直接忽略pMessage参数,调用时传nullptr即可 } int decodeHdr(const MsgHeader* pHeader, const unsigned char* msgBody, int msgBodyLen, void* decodedMsg) { // 逻辑中直接忽略decodedMsg参数,调用时传nullptr即可 } // 定义HDRONLY using HDRONLY= msgid<-1,void,encodeHdr,decodeHdr>;
方案2:使用空结构体作为占位类型(类型更安全)
定义一个空的占位结构体,避免void*的弱类型问题,调用时直接传nullptr即可(nullptr可以隐式转换为任意指针类型):
struct EmptyHdrMsg {}; int encodeHdr(const MsgHeader* pHeader, const EmptyHdrMsg* pMessage, unsigned char* destBuf, int destBufSize) { // 忽略pMessage参数 } int decodeHdr(const MsgHeader* pHeader, const unsigned char* msgBody, int msgBodyLen, EmptyHdrMsg* decodedMsg) { // 忽略decodedMsg参数 } // 定义HDRONLY using HDRONLY= msgid<-1,EmptyHdrMsg,encodeHdr,decodeHdr>;
方案3:偏特化msgid模板(最规范实现)
如果仅头消息的场景使用较多,可以针对MSGNUM < 0的情况做偏特化,移除不必要的MSG参数,完全匹配直接传nullptr的需求:
// 主模板保持原有定义不变 template <int MSGNUM, typename MSG, int(&ENCODER)(const MsgHeader* pHeader, const MSG* pMessage, unsigned char* destBuf, int destBufSize), int(&DECODER)(const MsgHeader* pHeader, const unsigned char* msgBody, int msgBodyLen, MSG* decodedMsg)> struct msgid { using msg_type = MSG; static constexpr int msgnum = MSGNUM; static constexpr auto encoder = ENCODER; static constexpr auto decoder = DECODER; }; // 仅头消息的偏特化实现 template <int MSGNUM, int(&ENCODER)(const MsgHeader* pHeader, std::nullptr_t pMessage, unsigned char* destBuf, int destBufSize), int(&DECODER)(const MsgHeader* pHeader, const unsigned char* msgBody, int msgBodyLen, std::nullptr_t decodedMsg)> struct msgid<MSGNUM, void, ENCODER, DECODER> { static constexpr int msgnum = MSGNUM; static constexpr auto encoder = ENCODER; static constexpr auto decoder = DECODER; }; // 对应HDRONLY定义 using HDRONLY= msgid<-1,void,encodeHdr,decodeHdr>;
内容的提问来源于stack exchange,提问作者jpo234
相关产品推荐
相关产品推荐

