Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/144.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++使用带字符串的标准算法,带有整数的函数,函数转换_C++_String_Algorithm_Function_Casting - Fatal编程技术网

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

C++使用带字符串的标准算法,带有整数的函数,函数转换,c++,string,algorithm,function,casting,C++,String,Algorithm,Function,Casting,我想以最短的代码方式计算字符串中的所有数字。我试过这样做: #include <string> #include <algorithm> unsigned countNumbers(const std::string s) { return count_if(s.begin(), s.end(), isdigit); } 我还尝试了更长的版本,这会产生相同的编译错误: unsigned countNumbers(const std::string s) {

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

#include <string>
#include <algorithm>

unsigned countNumbers(const std::string s) {
    return count_if(s.begin(), s.end(), isdigit);
}
我还尝试了更长的版本,这会产生相同的编译错误:

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*fint函数,这些函数需要bool*fint,而无需创建适配器函数和使用lambda表达式

当我知道如何解决问题时,我还有更多的问题需要解决,例如:

检查字符串是否可打印:如果不可打印,则查找。开始、结束、isprint 检查字符串是否包含,.!?…:如果s.begin、s.end、ispunct,则查找_ 还有更多。。。 我只想知道如何在标准C++中有更多的字符串可能性,这要感谢STD::
我在Internet上搜索了很长时间,找到了,但没有找到解决方案

使用函数指针解析类型:

unsigned countNumbers(const std::string s) {
    int (*isdigit)(int) = std::isdigit;
    return count_if(s.begin(), s.end(), isdigit);
}

别忘了包括在内

您可以使用静态强制转换来解析函数。或者,如果这是您经常想做的事情,您可以使用模板来解决它:

#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>("");
}

静态_cast是解决歧义的常用方法-它总是按照您的期望执行,并且可以是更大表达式的一部分

我发现以下方法同样有效:

    #include <ctype.h>
    count_if(s.begin(), s.end(), ::isdigit); //explicitly select the C version of isdigit 
但我必须指出,只有将C版本定义为函数时,它才能工作 而不是宏


因此,std::isdigit的静态转换可能是平台中最好的可移植解决方案。

我将给出另外两种解决方案来解决std::isdigit的歧义

使用lambda表达式:

std::count_if s.begin,s.end,[]字符c{return std::isdigitc;}

或使用显式强制转换:

std::count_if(s.begin(), s.end(), [](char c){ return std::isdigit(static_cast<int>(c)) != 0; })
使用显式模板类型您还需要编写迭代器类型:
std::count_如果s.begin、s.end、std::isdigit

无法再现错误,可与g++4.7.2 Win7x64、MinGW配合使用。编辑:如果我使用std::isdigit而不是isdigit,则会失败。如果您谈论的是来自标头的函数,则它们都是。将返回int作为谓词的函数传递给算法不是问题。算法是根据它们应用的操作而不是谓词的签名来指定的。也就是说,如果fx。。。不要求f返回bool,只要求其返回类型在上下文中可转换为bool。int的返回类型在这里可以正常工作。错误消息表示它无法在isdigit的重载版本之间进行选择,而不是isdigit的返回类型错误。答案给出了解决方案,但没有给出原因:在模板bool isdigit_图表、const locale和;您仍然可以使用isdigit作为@Zeta,以避免歧义。只要函数有一个重载,编译器就无法从算法函数中的用法推断可能函数的签名。我已经阅读了check重载集,但它没有明确地声明它。
#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>("");
}
    #include <ctype.h>
    count_if(s.begin(), s.end(), ::isdigit); //explicitly select the C version of isdigit 
std::count_if(s.begin(), s.end(), [](char c){ return std::isdigit(static_cast<int>(c)) != 0; })