显然,给定两个模板,一个从T *中推导出T,另一个从T&推断T,当与原始指针一起使用时,T&模板被实例化,而不是T *(MSVC13):
// throws if the given object's space isn't all zero
void VerifyZero(const void * ptr, size_t size);
template <typename T> void VerifyZero(const T * ptr)
{
VerifyZero(ptr, sizeof(T));
}
template <typename T> void VerifyZero(const T & ref)
{
VerifyZero(&ref, sizeof(T));
}
我真的,真的不想要T&amp;在以下内容中取代T *:
PODStruct * p = ... /* malloc or something, right now doesn't matter... */
VerifyZero(p); // <- why in the 7 hells does this resolve to &p, sizeof(PODStruct*)???
显然,我可以省略模板的参考版本,但是当我真的想要通过引用将POD结构清零时,那就太糟糕了。
答案 0 :(得分:6)
您获得一次const PODStruct *
(T = PODStruct
)重载,另一次重载PODStruct * const &
(T = PODStruct *
)。第二个重载是更好的匹配,因为p
是指向非const
数据的指针,因为p
是左值。
您可以解决此问题,例如使用带有第二个重载的enable_if
来拒绝指针类型。或者,正如评论中所建议的那样,为非const
限定的指针提供重载。
更好的是,IMO肯定会放弃过载。单个模板函数的可读性增加超过了您偶尔需要输入的额外&
。
答案 1 :(得分:1)
如果您将指针更改为非const template <typename T> void VerifyZero( T * ptr)
,那么它会解析您想要的方式,因为它比参考版本更好。
或者,如果你像这样创建它:PODStruct const* p = new PODStruct;
那么它也会解析你想要的方式。