"有趣"和"有趣"之间的类型差异?

NPS*_*NPS 30 c++ types function-pointers language-lawyer

表达式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;
Run Code Online (Sandbox Code Playgroud)

两个断言都成功,这表明两个表达式都具有相同的类型.然而,typeids返回不同的结果:

FvvE
PFvvE
Run Code Online (Sandbox Code Playgroud)

这是为什么?

use*_*670 28

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

static_assert(is_same<void(*)(), decltype(fun)>::value);
static_assert(is_same<void(*)(), decltype(&fun)>::value);
Run Code Online (Sandbox Code Playgroud)

在线编译器


son*_*yao 17

fun并且&fun由于指针转换功能而引用相同的类型,这是执行的check<void(*)()>(fun);; 但是typeid例外.

(强调我的)

不执行左值到右值,数组到指针或函数到指针的转换.

为什么执行指针转换的函数check<void(*)()>(fun);,因为在模板参数推导中,

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

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

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

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


Som*_*ude 6

当您使用函数名作为表达式时,它会衰减到指向自身的指针.所以fun将是一样的&fun.

至于typeid事情,从这个参考:

不执行左值到右值,数组到指针或函数到指针的转换.

[强调我的]