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; })