2017-09-14 71 views
2

爲什麼大多數C++編譯器能夠推斷出::isspace的類型並將其隱式轉換爲std::function,但是他們無法爲std::isspace這麼做?在C++中,爲什麼<cctype>定義了std :: isspace和:: 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 

由編譯器Explorer支持的編譯器,ELLCC似乎是唯一一所在std::isspace有deducibility /兌換,我期望的那樣。

+1

這就是爲什麼它更好地使用普通的'.h'頭文件,因爲它們是可以預測的 – stackptr

+0

我認爲它與'使用'有關' – o11c

回答

6

有多個過載std::isspace,但只有一個::isspace

頭文件< cctype>聲明瞭一個函數int std::isspace(int),它也可能在全局名稱空間中聲明瞭相同的函數(但並不一定)。

標頭<區域設置>定義功能模板template <class CharT> bool std::isspace(CharT, const std::locale&)

頭文件< ctype.h>聲明瞭一個函數int isspace(int),它也可以在名字空間std中聲明相同的函數(雖然它不是必須的)。

這很可能是在除了ELLCC編譯器,< cctype>包括<區域設置>(或兩者std::isspace重載聲明別的地方,包括到兩個頭)。標準只規定了標準頭文件必須聲明的符號;它並不禁止他們宣佈其他不需要的符號。

由於std::isspace已超載,因此您必須將其轉換爲int(*)(int),以便編譯器知道選擇哪個超載。

+0

Godbolt的ellcc似乎使用libC++,而另一些則使用libstdC++。在後一種情況下,拉入'''std :: isspace'的頭實際上是''。 –

相關問題