我已阅读有关此标准转换的现有问题。 但是,我没有找到令人满意的答案。
我有这段代码,表明T*
重载超过了T&&
。根据我的理解,转发引用重载应绑定所有内容,除非另一个重载是完美匹配。
在以下代码中,tab
是char const(&)[4]
。
有人可以向我解释为什么在这里执行数组到指针的转换吗? 如果有办法解决这种转换问题,我全都听见了!
(coliru link)
#include <utility>
template <typename T>
void f(T&& lol)
{
}
template <typename T>
void f(T* pof)
{
static_assert(sizeof(T) && false, "");
}
template <typename T>
struct S;
int main(int argc, char *argv[])
{
decltype("lol") tab = "lol";
S<decltype(tab)> s;
f("lol");
return 0;
}
答案 0 :(得分:5)
数组被推导为Ptr类型。
请参阅DVarga
在扣除开始之前,对P和A进行以下调整 制成:
1)如果P不是参考类型,
a)如果A是数组类型,则A由从数组到指针转换获得的指针类型替换;
b)否则,如果A是函数类型,则A将被从函数到指针转换获得的指针类型替换;
c)否则,如果A是cv限定类型,则忽略顶级cv限定符以进行演绎
答案 1 :(得分:3)
如果f
的参数对应的任意类型可以推导到{{1}的参数,则单参数函数模板g
被认为比模板f
更专业。但是,反之亦然。
任意指针类型g
都可以推导到T*
,但这并不是相反的方向(T&&
在一般情况下不能推导到T&&
),因此T*
被认为比f(T*)
更专业。
要解决此问题,我们必须使f(T&&)
对编译器的吸引力降低,例如使用SFINAE:
f(T*)