我如何获得一个模板来支持 T* 而不是 T&?

How do I get a template to favor T* over T&?

显然,给定两个模板,一个从 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& 在以下内容中取代 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 结构归零时,这就很糟糕了。

你得到一个重载 const PODStruct * (T = PODStruct),另一个重载 PODStruct * const & (T = PODStruct *)。第二个重载是更好的匹配,因为 p 是一个指向非 const 数据的指针,并且 p 是一个左值。

您可以解决这个问题,例如使用 enable_if 和第二个重载来拒绝指针类型。或者,如评论中所建议的,为非 const 限定的指针提供重载。

更好的是,IMO,但肯定会放弃过载。单个模板函数增加的可读性远远超过您偶尔需要输入的额外 &

如果您将指针更改为非常量 template <typename T> void VerifyZero( T * ptr),那么它会按照您想要的方式解析,因为它比参考版本更匹配。

或者,如果您这样创建它:PODStruct const* p = new PODStruct; 那么它也会按照您想要的方式解析。