c++ - 为什么 std::function 不参与重载决议?
问题描述
我知道下面的代码不会编译。
void baz(int i) { }
void baz() { }
class Bar
{
std::function<void()> bazFn;
public:
Bar(std::function<void()> fun = baz) : bazFn(fun){}
};
int main(int argc, char **argv)
{
Bar b;
return 0;
}
因为std::function
据说不考虑重载解决方案,正如我在另一篇文章中所读到的那样。
我不完全理解迫使这种解决方案的技术限制。
我在 cppreference 上阅读了关于翻译和模板的阶段,但我想不出任何我找不到反例的推理。向半门外汉(对 C++ 还是新手)解释,是什么以及在哪个翻译阶段导致上述编译失败?
解决方案
这与“翻译阶段”没有任何关系。这纯粹是关于std::function
.
看,std::function<R(Args)>
不要求给定的函数完全是 type R(Args)
。特别是,它不需要给它一个函数指针。它可以采用任何可调用类型(成员函数指针,一些具有 重载的对象operator()
),只要它是可调用的,就好像它接受Args
参数并返回可转换为的 R
东西(或者如果R
是void
,它可以返回任何东西)。
为此,适当的构造函数std::function
必须是模板:template<typename F> function(F f);
。也就是说,它可以采用任何函数类型(受上述限制)。
该表达式baz
表示一个重载集。如果您使用该表达式来调用重载集,那很好。如果将该表达式用作采用特定函数指针的函数的参数,C++ 可以将重载集缩减为单个调用,从而使其正常。
但是,一旦函数是模板,并且您使用模板参数推导来确定该参数是什么,C++ 就不再能够确定重载集中正确的重载是什么。所以你必须直接指定它。
推荐阅读
- mongodb - Mongo:使用 .find({_id: id}) 与 .findOne({_id: id}) 是否相同?
- java - OpenMath-Objects 可以在相等性方面与另一个进行比较吗?
- javascript - 如何在 R 闪亮中动态移动 UI 元素(主要是 mainPanel)?
- javascript - 如何仅在单击确定按钮后才使元素 UI 时间选择器设置值?
- c++ - 对包含数字和单词的字符串向量进行排序
- php - 正则表达式 301 重定向不起作用
- php - PHP 表单/准备好的语句错误
- android - Flutter App 几乎与所有东西都不兼容?
- xamarin - 在 xamarin 表单中更改 Windows.UI.Xaml.Controls.DatePicker 弹出窗口的 FontSize
- r - 如何找到正态分布的切割点(有序数据案例) - R