函数到指针引用的转换

function to pointer reference conversion

我想知道为什么下面的代码是正确的:

void foo(){}
void foo2(void(*)()){};
void foo3(void(*)()&){};

int main(){
  foo; // type void(&)() lvalue
  foo2(foo); // void(&)() -> void(*)() function to pointer conversion
  foo3(foo); // ?? conversion
}

根据function to pointer转换here

An lvalue of function type T can be converted to a prvalue of type “pointer to T”. The result is a pointer to the function.

从 void(&)() 到 void(*)() 的转换没问题,但不是 void(*)()&。

为什么这个代码片段(尤其是 ?? 行)是正确的?

foo3的参数void(*)()&实际上是一个带有ref-qualifier的函数指针。这是标准不允许的。

C++17 标准草案 n4659 指出:

[dcl.fct]/6

A function type with a cv-qualifier-seq or a ref-qualifier (including a type named by typedef-name) shall appear only as:

(6.1) — the function type for a non-static member function,
(6.2) — the function type to which a pointer to member refers,
(6.3) — the top-level function type of a function typedef declaration or alias-declaration,
(6.4) — the type-id in the default argument of a type-parameter, or
(6.5) — the type-id of a template-argument for a type-parameter.

foo3的参数不符合以上任何条件。最接近你正在尝试做的是(6.2)。

所以你可以用这个代替:

void foo(){}
class C {
public:
    void foo1() & {}
};
void foo2(void(*)()){};
void foo3(void(C::*)()&){};

int main(){
  (void) foo; 
  foo2(foo); 
  foo3(&C::foo1); 
}

这可以在 GCC 和 Clang 上编译。 Demo here.