函数指针引用转换

问题描述 投票:2回答:1

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

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

函数类型T的左值可以转换为“指向T的指针”的prvalue。结果是指向函数的指针。

从void(&)()到void(*)()的转换很好,但不是void(*)()&。

这段代码片段(特别是与??一起排列)的正确原因是什么?

c++ type-conversion implicit-conversion
1个回答
0
投票

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

C ++ 17标准草案n4659规定:

[dcl.fct]/6

具有cv-qualifier-seq或ref-qualifier(包括由typedef-name命名的类型)的函数类型应仅显示为:

(6.1) - 非静态成员函数的函数类型, (6.2) - 指向成员的指针引用的函数类型, (6.3) - 函数typedef声明或别名声明的顶级函数类型, (6.4) - type-parameter的默认参数中的type-id,或 (6.5) - 类型参数的template-argument的type-id。

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

© www.soinside.com 2019 - 2024. All rights reserved.