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



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

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),但是当我第二次找到标准差时,我需要除以大小 1 (n-1)。

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

几乎。根据表 96 - N3797 中的容器要求,标准库中的所有容器都必须提供成员函数size。它应具有恒定的执行时间,并返回容器adistance(a.begin(),a.end()) 值。

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

forward_list满足容器的所有要求(表 96),除了 size() 成员 未提供功能。

(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>

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

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

相关内容

最新更新