“fun”和“& fun”之间的类型差异?

时间:2018-01-23 10:04:20

标签: c++ types language-lawyer function-pointers

表达式fun&fun是否具有相同的类型?

请考虑以下代码:

template <typename Check, typename T>
void check(T)
{
    static_assert(is_same<Check, T>::value);
}

void fun()
{}

check<void(*)()>(fun);
check<void(*)()>(&fun);

cout << typeid(fun).name() << endl;
cout << typeid(&fun).name() << endl;

两个断言都成功,这表明两个表达式具有相同的类型。但是,typeid会返回不同的结果:

FvvE
PFvvE

为什么?

3 个答案:

答案 0 :(得分:29)

两个断言都成功,因为它们应用于从函数参数推导出的类型T。在这两种情况下,它都将被推断为函数的指针,因为函数会衰减为指向函数的指针。但是,如果您重写断言以直接接受类型,那么第一个将失败:

static_assert(is_same<void(*)(), decltype(fun)>::value);
static_assert(is_same<void(*)(), decltype(&fun)>::value);

online compiler

答案 1 :(得分:17)

fun&fun引用相同的类型,因为function to pointer conversion是在check<void(*)()>(fun);中执行的;但是typeid是一个例外。

(强调我的)

  

Lvalue-to-rvalue,array-to-pointer或函数到指针的转换未执行

为什么要对check<void(*)()>(fun);执行指针转换功能,因为在template argument deduction中,

  

在扣除开始之前,会对 P A 进行以下调整:

     

1)如果 P 不是参考类型,

     
      
  • 如果 A 是数组类型,...;
  •   
  • 否则,如果 A 是函数类型, A 将替换为从函数到指针转换获得的指针类型;
  •   

check()按值获取参数,然后执行函数到指针的转换,推导出的T类型也将是函数指针,即void(*)()

答案 2 :(得分:6)

当您使用函数名作为表达式时,它衰减指向自身的指针。因此fun&fun相同。

关于typeid事,来自this reference

  

不执行Lvalue-to-rvalue,数组到指针或函数到指针转换。

[强调我的]