2013-07-10 54 views
3

我有一段代碼,該代碼在運行std::vector<double> cats並做這樣的事情:如何請使用isNaN作謂語功能爲std :: find_if(C++ 11)

std::find_if(cats.begin(), cats.end(), std::isnan<double>); 

這個編譯在4.3之前的gcc下,但不再使用gcc 4.7.2編譯。我得到這樣一個錯誤:

error: no matching function for call to 'find_if(std::vector<double>::iterator, std::vector<double::iterator, <unresolved overloaded function type>)' 

我如何能得到這個在新的gcc編譯?最好還在舊的gcc下?沒有擺脫stl和手動編寫循環當然。如果兩者都不可行,那麼新的gcc就足夠了,我將把這兩個實現都留在#define之內。

+0

'std :: isnan '??在C++ 11標準中,isnan是一個非模板函數。在C99中它是一個宏。 –

+0

我確實讀過,但它以某種方式編譯 –

+0

它曾經是早期版本的GCC中的模板。在GCC 4.7中有三個重載_and_整型 –

回答

7

你真正想要的過載是不是在GCC 4.7的模板,它只是與此簽名正常功能:

bool isnan(double); 

(有一個模板,但SFINAE意味着它僅適用於整數類型。 )

但在以前的版本中,它是一個模板,所以沒有一個簡單的便攜方式來接收它的地址。

既然你說C++ 11,你可以使用lambda,讓拉姆達的身體做重載決議找到合適的過載(或模板特):否則

std::find_if(cats.begin(), cats.end(), [](double d) { return std::isnan(d); }); 

對於C++ 03你可以提供自己的轉發包裝:

struct IsNan { 
    double operator()(double d) const { return std::isnan(d); } 
}; 
std::find_if(cats.begin(), cats.end(), IsNan()); 
+0

的模板非常好!我想知道是否有一行代碼可以爲兩者編譯? –

+0

有趣的是,在gcc 4.7.2中,給出了「錯誤:沒有上下文類型信息的重載函數」 –

+1

該模型也適用於模板(假設簽名是正確的:'bool(*)(double)')。 –

4

在C++ 11,isnan是一組三個重載爲不同的浮點類型floatdoublelong double。您可以通過使用轉換語法解析你想要的過載:

std::find_if(cats.begin(), cats.end(), 
      static_cast<bool (*)(double)>(std::isnan)); 

當然,正如喬納森建議使用拉姆達的可能,如果你的目標平臺都支持lambda表達式是維護清晰。

+0

此演員陣容適用於gcc 4.7.2,但它在4.1.2 –

+0

下給出「錯誤:無效static_cast從類型'<無法解析的重載函數類型>'鍵入'bool(*)(double)'」這是我第一次嘗試,但我愚蠢地得到了返回類型錯誤,並在GCC 4.1的''它返回'int' –

+0

@JonathanWakely:Ouch ...所以它有C99簽名。所以不是真的便攜式。 –