count_occurences
代码查找字符串中位置c
(包含)和start
(排除)之间字符end
出现的次数。例如。下面的代码计算,
中的,b,
(a,b,c
从1
到4
的子串),即2
。
#include <iostream>
#include <algorithm>
size_t count_occurences(const std::string& str, char c, size_t start, size_t end) {
return std::count(str.begin() + start, str.begin() + end, c);
}
int main() {
std::string str = "a,b,c";
size_t start = 1, end = 4;
std::cout << count_occurences(str, ',', start, end);
return 0;
}
使用
clang++ -Wconversion
编译时,我收到以下警告:
a.cpp:5:12: warning: implicit conversion changes signedness: '_Iter_diff_t<_String_const_iterator<_String_val<_Simple_types<char>>>>' (aka 'long long') to 'size_t' (aka 'unsigned long long') [-Wsign-conversion]
5 | return std::count(str.begin() + start, str.begin() + end, c);
| ~~~~~~ ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
a.cpp:5:58: warning: implicit conversion changes signedness: 'size_t' (aka 'unsigned long long') to 'difference_type' (aka 'long long') [-Wsign-conversion]
5 | return std::count(str.begin() + start, str.begin() + end, c);
| ~ ^~~
a.cpp:5:37: warning: implicit conversion changes signedness: 'size_t' (aka 'unsigned long long') to 'difference_type' (aka 'long long') [-Wsign-conversion]
5 | return std::count(str.begin() + start, str.begin() + end, c);
| ~ ^~~~~
在不更改 count_occurences
static_cast
,但这更多的是消除警告而不是修复它。(在实际代码中,
start
和
end
是字段,因此该函数只有2个参数。)
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wconversion"
size_t count_occurences(const std::string& str, char c, size_t start, size_t end) {
return std::count(str.begin() + start, str.begin() + end, c);
}
#pragma clang diagnostic pop
请注意,GCC 会向您发出有关无法识别的编译指示的警告,因此您实际上需要的不仅仅是这个。
_Pragma
可以帮助您最大限度地减少这种情况,但它仍然比仅使用
size_t
要复杂得多。
size_t count_occurences(const std::string& str, char c, size_t start, size_t end) {
return std::count(str.begin() + static_cast<ptrdiff_t>(start),
str.begin() + static_cast<ptrdiff_t>(end),
c);
}
这仍然是最自我记录的解决方案。
这可能不是一个令人满意的答案,但这是正确的方法。根本问题是迭代器通常需要一个有符号整数,例如
ptrdiff_t
,而您正在使用无符号整数进行数学运算。 您的警告不是误报,并且
static_cast
将记录您意识到这些类型差异并有意进行转换。
注意:@TimRoberts 还指出你可以写 std::count(&str[start], &str[end], c);
。此解决方案仅适用于连续容器,但它比
static_cast
更紧凑。