如何通过T&amp ;?获得模板以支持T *?

时间:2015-01-15 19:24:12

标签: c++ templates metaprogramming

显然,给定两个模板,一个从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结构清零时,那就太糟糕了。

2 个答案:

答案 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;那么它也会解析你想要的方式。