从 <algorithm> 中更正 return 类型的 count()
Correct return type of count() from <algorithm>
警告,这太挑剔了!
大多数人将 count() 来自 algorithm 的结果存储在某种 signed integer 中,即 long*输入或 ptr_diff 来自 cstddef:
vector<int> vec = {0, 0, 1, 1, 1,};
long result = count(vec.cbegin(), vec.cend(), 1); // result == 3
一种现代而懒惰的方法:
auto result = count(vec.cbegin(), vec.cend(), 1);
两个都很好。如果底层原始类型发生变化,第一个可能会成为问题。第二个保证类型正确,但类型未知(程序员)。在类型化语言中,程序员应该知道所涉及的库类型,而不一定是所涉及的原始类型。想象一个 returns 和 unsigned 的算法,后来程序意外地使用 unsigned 和 signed 变量。查看 cppreference.com 显示 C++11:
template< class InputIt, class T >
typename iterator_traits<InputIt>::difference_type
count( InputIt first, InputIt last, const T &value );
我认为返回类型的定义是:
iterator_traits<vector<int>::const_iterator>::difference_type result = count(vec.cbegin(), vec.cend(), 1);
我不认为这是最佳做法!我只想知道类型,但不想在实践中使用该定义。 vector的difference_type好像也是一个选择,count函数不是来自容器,而是来自它的迭代器。我对变量 result 的定义是否正确?
谢谢
PS:GCC 7.2在X86_64GNU/Linux上使用的底层类型确实long,至少 typeid 告诉我的。
的确,在
auto result = count(vec.cbegin(), vec.cend(), 1);
auto
是 std::iterator_traits<std::vector<int>::const_iterator>::difference_type
。
std::count is of std::iterator_traits<InputIt>::difference_type
type which is of std::ptrdiff_t 类型是 typedef
为 有符号整数 类型定义的实现。所以最终它是实现定义的。可能的实现给出了线索:
template<class InputIt, class T>
typename iterator_traits<InputIt>::difference_type // <--
count(InputIt first, InputIt last, const T& value)
{
typename iterator_traits<InputIt>::difference_type ret = 0;
for (; first != last; ++first) {
if (*first == value) {
ret++;
}
}
return ret; // <--
}
警告,这太挑剔了!
大多数人将 count() 来自 algorithm 的结果存储在某种 signed integer 中,即 long*输入或 ptr_diff 来自 cstddef:
vector<int> vec = {0, 0, 1, 1, 1,};
long result = count(vec.cbegin(), vec.cend(), 1); // result == 3
一种现代而懒惰的方法:
auto result = count(vec.cbegin(), vec.cend(), 1);
两个都很好。如果底层原始类型发生变化,第一个可能会成为问题。第二个保证类型正确,但类型未知(程序员)。在类型化语言中,程序员应该知道所涉及的库类型,而不一定是所涉及的原始类型。想象一个 returns 和 unsigned 的算法,后来程序意外地使用 unsigned 和 signed 变量。查看 cppreference.com 显示 C++11:
template< class InputIt, class T >
typename iterator_traits<InputIt>::difference_type
count( InputIt first, InputIt last, const T &value );
我认为返回类型的定义是:
iterator_traits<vector<int>::const_iterator>::difference_type result = count(vec.cbegin(), vec.cend(), 1);
我不认为这是最佳做法!我只想知道类型,但不想在实践中使用该定义。 vector的difference_type好像也是一个选择,count函数不是来自容器,而是来自它的迭代器。我对变量 result 的定义是否正确?
谢谢
PS:GCC 7.2在X86_64GNU/Linux上使用的底层类型确实long,至少 typeid 告诉我的。
的确,在
auto result = count(vec.cbegin(), vec.cend(), 1);
auto
是 std::iterator_traits<std::vector<int>::const_iterator>::difference_type
。
std::count is of std::iterator_traits<InputIt>::difference_type
type which is of std::ptrdiff_t 类型是 typedef
为 有符号整数 类型定义的实现。所以最终它是实现定义的。可能的实现给出了线索:
template<class InputIt, class T>
typename iterator_traits<InputIt>::difference_type // <--
count(InputIt first, InputIt last, const T& value)
{
typename iterator_traits<InputIt>::difference_type ret = 0;
for (; first != last; ++first) {
if (*first == value) {
ret++;
}
}
return ret; // <--
}