指针引用转换功能

时间:2019-02-24 16:08:07

标签: c++ type-conversion implicit-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

  

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

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

此代码段(尤其是??)正确的原因是什么?

1 个答案:

答案 0 :(得分:0)

foo3的参数void(*)()&实际上是具有引用限定符的函数指针。该标准不允许这样做。

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

[dcl.fct]/6

  

具有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