C++ 函数到指针引用的转换

C++ 函数到指针引用的转换,c++,type-conversion,implicit-conversion,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 } 根据函数到指针

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

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
}
根据
函数到指针的转换

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

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


这个代码段(特别是带???的行)正确的原因是什么?

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

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

带有cv限定符seq或ref限定符的函数类型(包括由typedef name命名的类型)应仅显示为

(6.1)-非静态成员函数的函数类型,
(6.2)-指向成员的指针所指的函数类型,
(6.3)-函数类型定义声明或别名声明的顶级函数类型,
(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上编译。
.

我怀疑它与函数“转换”类型(
void(C::*)()&
->
void(*)()()&
void(*)()&
)的方法相同。当前没有指向
foo
的指针,您可以在其上引用它?来自clang btw的错误:“指向函数类型的指针不能有'&'限定符”@Jarod42您是对的,那可能是不允许的。GCC不会发出任何类型的警告。对于一些使用的
,GCC会提供错误,它的行为对我来说似乎是一个bug……这样的注释通常描述了一些在其他地方以不易访问的方式规范性地陈述的内容。它声称要形成自己的规则是不寻常的(因为这根本没有法律意义)。因此,我希望我们会发现编译器没有任何回旋余地,但我们需要找到规范性原因。还有,函数类型的引用在哪里?