为什么大多数C ++编译器能够推导出::isspace
的类型并隐式将其转换为std::function
,但他们无法对std::isspace
执行此操作?
请参阅无法编译的the following:
#include <cctype>
#include <functional>
template <typename Functish>
bool bar1(Functish f) { return f('a'); }
inline bool bar2(std::function<bool(char)> f) { return f('a'); }
#if 1
#define ff &std::isspace
#else
#define ff &::isspace
#endif
#if 0
bool foo()
{
return bar1(ff);
}
#else
bool foo()
{
return bar2(ff);
}
#endif
在Compiler Explorer支持的编译器中,ELLCC似乎是唯一std::isspace
具有我期望的可推导性/可转换性的编译器。
答案 0 :(得分:6)
std::isspace
有多个重载,但只有一个::isspace
。
标题&lt; cctype&gt;声明一个函数int std::isspace(int)
,它也可能在全局命名空间中声明相同的函数(但它不必)。
标题&lt; locale&gt;定义了一个函数模板template <class CharT> bool std::isspace(CharT, const std::locale&)
。
标题&lt; ctype.h&gt;声明一个函数int isspace(int)
,它也可以在命名空间std
中声明相同的函数(但它不必)。
似乎在ELLCC以外的编译器上,&lt; cctype&gt;包括&lt; locale&gt; (或两个std::isspace
重载都在其他地方声明并包含在两个头文件中)。标准仅指定标准头必须声明的符号;它并不禁止他们声明其他不需要的符号。
由于std::isspace
被重载,您必须将其强制转换为int(*)(int)
,以便编译器知道要选择哪个重载。