我想知道为什么以下代码正确:
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的指针”的前值。 结果是指向该函数的指针。
从void(&)()到void(*)()的转换很好,但不是void(*)()&。
此代码段(尤其是??)正确的原因是什么?
答案 0 :(得分:0)
foo3
的参数void(*)()&
实际上是具有引用限定符的函数指针。该标准不允许这样做。
C ++ 17标准草案n4659指出:
具有cv-qualifier-seq 或ref-qualifier 的函数类型(包括以typedef-name命名的类型)应仅显示为:
(6.1)—非静态成员函数的函数类型,
(6.2)—指向成员的指针所引用的函数类型,
(6.3)—函数typedef声明或别名声明的顶级函数类型,
(6.4)—类型参数的默认参数中的类型ID,或
(6.5)—类型参数的模板参数的类型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。