从<algorithm>

时间:2018-01-29 15:35:46

标签: c++ algorithm auto

警告,这很挑剔!
大多数人将 count()的结果从算法存储到某种有符号整数即long * type或 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);

两者都很好。如果底层基元类型发生变化,第一个可能会成为问题。第二个保证正确的类型,但类型是未知的(由程序员)。在类型语言中,程序员应该知道所涉及的库类型,而不一定是所涉及的基元类型。想象一个算法,它返回 unsigned ,之后程序意外地使用 unsigned signed 变量。查看C ++ 11的cppreference.com节目:

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

我并不认为这是最佳做法!我只是想知道类型,但不是在实践中使用该定义。向量的 difference_type 似乎也是一个选择, count 函数不是来自容器,而是来自它的迭代器。我对变量 result 的定义是否正确?
谢谢

PS:GCC 7.2在X86_64 GNU / Linux上使用的基础类型实际上是 long ,至少 typeid 告诉我。

2 个答案:

答案 0 :(得分:3)

确实,在

auto result = count(vec.cbegin(), vec.cend(), 1);

autostd::iterator_traits<std::vector<int>::const_iterator>::difference_type

答案 1 :(得分:3)

std::count属于std::iterator_traits<InputIt>::difference_type类型,属于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; // <--
}