C++使用带字符串的标准算法,带有isdigit的count_if,函数转换

baz*_*rek 8 c++ string algorithm casting function

我想以最短的代码方式计算字符串中的所有数字.我试过这样的方式:

#include <string>
#include <algorithm>

unsigned countNumbers(const std::string s) {
    return count_if(s.begin(), s.end(), isdigit);
}
Run Code Online (Sandbox Code Playgroud)

错误信息是:

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)
Run Code Online (Sandbox Code Playgroud)

我知道count_if()想要的函数如下:bool(*f)(char); 作为第三个参数,所以我试图强制转换函数:

unsigned countNumbers(const std::string s) {
    return count_if(s.begin(), s.end(), reinterpret_cast<bool (*)( char )>(isdigit));
}
Run Code Online (Sandbox Code Playgroud)

错误信息是:

a.cc: In function ‘unsigned int countNumbers(std::string)’:
a.cc:5:80: error: overloaded function with no contextual type information
Run Code Online (Sandbox Code Playgroud)

我也尝试了一个更长的版本,它给出了相同的编译错误:

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);
}
Run Code Online (Sandbox Code Playgroud)

我想避免的解决方案是创建一个适配器的函数:

#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);
}
Run Code Online (Sandbox Code Playgroud)

我的问题是如何在std :: algorithm的函数中使用函数int(*f)(int),这些函数需要bool(*f)(int)而不创建适配器函数而不使用lambda表达式?

当我知道如何解决问题时,我会遇到更多问题,例如:

  • 检查字符串是否可打印:find_if_not(s.begin(),s.end(),isprint)
  • 检查字符串是否包含",.!?...":find_if(s.begin(),s.end(),ispunct)等等...

我只是想知道如何在标准C++中有更多的字符串可能性,这要归功于我长时间在互联网上搜索的std :: algorithms,我发现了类似的问题,但我找不到解决方法

Fle*_*exo 6

您可以使用静态强制转换来解析该函数​​.或者,如果您想要做很多事情,可以使用模板来解决它:

#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>("");
}
Run Code Online (Sandbox Code Playgroud)

static_cast 是解决歧义的"通常"方式 - 它总能达到您的期望,并且可以成为更大表达的一部分.