[英]C++ using standard algorithms with strings, count_if with isdigit, function cast
我想以最短的代碼方式計算字符串中的所有數字。 我試過這樣的方式:
#include <string>
#include <algorithm>
unsigned countNumbers(const std::string s) {
return count_if(s.begin(), s.end(), isdigit);
}
錯誤信息是:
a.cc: In function ‘unsigned int countNumbers(std::string)’:
a.cc:5:45: error: no matching function for call to ‘count_if(std::basic_string<char>::const_iterator, std::basic_string<char>::const_iterator, <unresolved overloaded function type>)’
a.cc:5:45: note: candidate is:
/usr/include/c++/4.6/bits/stl_algo.h:4607:5: note: template<class _IIter, class _Predicate> typename std::iterator_traits<_InputIterator>::difference_type std::count_if(_IIter, _IIter, _Predicate)
我知道count_if()想要的函數如下:bool(* f)(char); 作為第三個參數,所以我試圖強制轉換函數:
unsigned countNumbers(const std::string s) {
return count_if(s.begin(), s.end(), reinterpret_cast<bool (*)( char )>(isdigit));
}
錯誤信息是:
a.cc: In function ‘unsigned int countNumbers(std::string)’:
a.cc:5:80: error: overloaded function with no contextual type information
我也嘗試了一個更長的版本,它給出了相同的編譯錯誤:
unsigned countNumbers(const std::string s) {
typedef bool ( * f_ptr )( char );
f_ptr ptr = reinterpret_cast<f_ptr>(isdigit);
return count_if(s.begin(), s.end(), ptr);
}
我想避免的解決方案是創建一個適配器的函數:
#include <string>
#include <algorithm>
bool is_digit(char c) {
return isdigit(c);
}
unsigned countNumbers(const std::string s) {
return count_if(s.begin(), s.end(), is_digit);
}
我的問題是如何在std :: algorithm的函數中使用函數int(* f)(int),這些函數需要bool(* f)(int)而不創建適配器函數而不使用lambda表達式?
當我知道如何解決問題時,我會遇到更多問題,例如:
我只是想知道如何在標准C ++中有更多的字符串可能性,這要歸功於我長時間在互聯網上搜索的std :: algorithms,我發現了類似的問題 ,但我找不到解決方法
您可以使用靜態強制轉換來解析該函數。 或者,如果您想要做很多事情,可以使用模板來解決它:
#include <string>
#include <cctype>
#include <algorithm>
unsigned count(const std::string& s) {
return std::count_if(s.begin(), s.end(), static_cast<int(*)(int)>(std::isdigit));
}
template <int(*Pred)(int)>
unsigned foo(const std::string& s) {
return std::count_if(s.begin(), s.end(), Pred);
}
int main() {
count("");
foo<std::isdigit>("");
foo<std::isprint>("");
}
static_cast
是解決歧義的“常用”方式 - 它始終按照您的期望行事,並且可以成為更大表達的一部分。
使用函數指針解析類型:
unsigned countNumbers(const std::string s) {
int (*isdigit)(int) = std::isdigit;
return count_if(s.begin(), s.end(), isdigit);
}
不要忘記包含<cctype>
。 ( 演示 )
我將給出另外兩個解決方案來修復<locale> std::isdigit
的歧義
使用lambda表達式:
std::count_if(s.begin(), s.end(), [](char c){ return std::isdigit(c); })
或使用顯式鑄造:
std::count_if(s.begin(), s.end(), [](char c){ return std::isdigit(static_cast<int>(c)) != 0; })
std::count_if<std::string::const_iterator, int(*)(int)>(s.begin(), s.end(), std::isdigit)
我發現以下也有效:
#include <ctype.h>
count_if(s.begin(), s.end(), ::isdigit); //explicitly select the C version of isdigit
但我必須弄清楚它只有在C版本定義為函數而不是宏時才有效
因此,std :: isdigit的static_cast可能是平台中最好的便攜式解決方案。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.