所有容器都有 .size() 函数吗?

Do all containers have a .size() function?

对于家庭作业,我必须创建一个可以在任何容器上执行的模板化标准偏差函数。这是我拥有的:

template <typename Container>
double findMean(Container c, int count){
    double sum = 0;
    for (auto&& e : c){
        sum += e;
    }
    sum /= count;
    return sum;
}

template <typename Container>
double findStDev(Container c){
    double mean = findMean(c, c.size());
    std::cout << mean << std::endl;
    for (auto&& e : c){
        e -= mean;
        e *= e;
    }
    mean = sqrt(findMean(c, c.size()));
    return mean;
}

第一次求均值我想除以容器的全尺寸(n),但是第二次求标准差时,我需要除以size-1(n -1).

.size() 函数是否适用于所有 C++ 容器?

差不多。通过table96-N3797中的容器要求,标准库中的所有容器都必须提供一个成员函数size。它应具有恒定的执行时间和 return 容器 a.

distance(a.begin(),a.end()) 的值

但是,有一个(也是唯一一个)例外,后面会提到:

A forward_list satisfies all of the requirements of a container (Table 96), except that the size() member function is not provided.

(N3797 23.3.4.1 第 2 条)

这意味着 std::forward_list 确实是一个标准容器 没有成员函数 size.

按照 STL 的优良传统,您可以让您的模板接受一对前向迭代器并在对元素求和时计算距离。

#include <cstddef>
#include <iterator>

template<typename FwdIter,
         typename value_type = typename std::iterator_traits<FwdIter>::value_type>
value_type
mean(const FwdIter begin, const FwdIter end)
{
  std::size_t count {0};
  value_type sum {};
  for (auto it = begin; it != end; ++it)
    {
      sum += *it;
      ++count;
    }
  return sum / count;
}

这将适用于标准库容器、数组、指针,无论您想要什么。对于容器,您可以简单地定义一个方便的转发模板,如果需要,可以调用 cbegincend

请注意,我在上面的示例中省略了任何类型约束。在实践中,您可能应该 std::enable_if 仅在特殊条件下使用模板,例如 if std::is_arithmetic<value_type>.

Do all containers have a .size() function?

没有。他们中的大多数人都这样做,并且在 C++11 之前,他们都这样做了。但是,C++11 看到了单链表 class 模板 std::forward_list 的引入,其中 没有 具有 size() 成员函数。所有其他容器都这样做,并且当前标准指定算法复杂度为 O(1)。在 C++11 之前,std::list 被允许具有线性复杂度。