限制函数指针的转换

The*_*Vee 7 c++ casting language-lawyer

我想知道为什么static_castint (*)(const int&)类型到int (*)(int&)非法.如果我有一个函数指针,在技术上允许接受int&但希望为其分配一个自愿放弃修改指向值的权限的函数,它不应该像原则上可以作为函数的特殊情况一样吗?

换句话说,鉴于我可以将一个任意函数传递int&给一个int (*)(const int&)函数,标准中有更深层次的原因,为什么后者不能被视为特殊情况int (*)(int&)并被分配给这样的变量?

M(!W)E:

int g(const int& q) {
  return q;
}

int main() {
  int (*f)(int&) = static_cast<int(*)(int&)>(g); // breaks
  int x = 1;
  return f(x);
}
Run Code Online (Sandbox Code Playgroud)

Bar*_*rry 5

[...]标准中有更深层次的原因为什么[...]

这些问题通常无法回答.也许没有人认为这是值得研究的事情.一般来说,C++对协方差和逆变的支持有限.还有许多其他可能的安全转换,而不仅仅是对引用进行限定.

例如,类似的函数指针Animal*(*)(Dog*)可以从两者Animal*(*)(Animal*)和/ 来初始化Dog*(*)(Dog*).但今天,两种转换都不受支持.

所以真正的答案可能是:撰写提案.


然而,在这种情况下,我们仍然可以通过一个明显被低估的规则来实现所期望的行为:几乎总是Lambda.我们知道,我们想要使用的函数,没有捕获的lambdas(我们不需要)可以转换为函数指针:

int (*f)(int&) = [](int& i) { return g(i); };
Run Code Online (Sandbox Code Playgroud)