代码之家  ›  专栏  ›  技术社区  ›  Frank

最佳实践:如何改进这个对容器值求和的代码?

  •  2
  • Frank  · 技术社区  · 14 年前

    我正在编写一个简单的函数,它对容器中的数字进行迭代,并计算一些汇总值(本例中的熵)。

    我想把它写得尽可能通用,这样它就可以与不同的容器一起工作( vector , set ,…)在不同的值类型上( double float ,…),所以我要这样做:

    template<class Iterator>
    typename Iterator::value_type Entropy(Iterator begin, Iterator end) {
      typedef typename Iterator::value_type Value;
      Value result = Value(); // assignment needed?
      for (Iterator it = begin; it != end; ++it) {
        result -= *it * log(*it);
      }
      return result;
    }
    

    根据所有的最佳实践,我对这段代码的样子很感兴趣。换句话说,这个小函数的STL实现到底是什么样子的?

    4 回复  |  直到 14 年前
        1
  •  4
  •   David    14 年前

    查看std::transform和std::accumulate

        2
  •  4
  •   Edward Strange    14 年前
    template < typename T1, typename T2 >
    T1 entropy_sum(T1 sum_so_far, T2 number)
    {
      return sum_so_far - static_cast<T1>(number) * log(static_cast<T1>(number));
    }
    double entropy = std::accumulate(set.begin(), set.end(), 0.0, &entropy_sum<double, set_type::value_type>);
    

    你的方法没问题,只是 Value() 可能不是法律声明。

        3
  •  4
  •   Steve Townsend    14 年前

    在C++ 0x中,可以使用以下lambda版本:

    template<class Iterator>
    typename Iterator::value_type Entropy(Iterator begin, Iterator end) {
      typedef typename Iterator::value_type Value;
      return accumulate(begin, end, Value(), 
          [] (Value i, Value j)-> Value { return i - j * log(j); });  
    }
    
        4
  •  2
  •   UncleBens    14 年前

    std::iterator_traits 为此:

    typedef typename std::iterator_traits<Iterator>::value_type Value;
    

    这允许迭代器作为指针。