模板类型推导执行隐式数组到指针转换

时间:2016-08-30 12:33:03

标签: c++ c++11

我已阅读有关此标准转换的现有问题。 但是,我没有找到令人满意的答案。

我有这段代码,表明T*重载超过了T&&。根据我的理解,转发引用重载应绑定所有内容,除非另一个重载是完美匹配。

在以下代码中,tabchar 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;
}

2 个答案:

答案 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*)