<bdo id='wrMTu'></bdo><ul id='wrMTu'></ul>
<i id='wrMTu'><tr id='wrMTu'><dt id='wrMTu'><q id='wrMTu'><span id='wrMTu'><b id='wrMTu'><form id='wrMTu'><ins id='wrMTu'></ins><ul id='wrMTu'></ul><sub id='wrMTu'></sub></form><legend id='wrMTu'></legend><bdo id='wrMTu'><pre id='wrMTu'><center id='wrMTu'></center></pre></bdo></b><th id='wrMTu'></th></span></q></dt></tr></i><div id='wrMTu'><tfoot id='wrMTu'></tfoot><dl id='wrMTu'><fieldset id='wrMTu'></fieldset></dl></div>
  • <small id='wrMTu'></small><noframes id='wrMTu'>

      <tfoot id='wrMTu'></tfoot>
      <legend id='wrMTu'><style id='wrMTu'><dir id='wrMTu'><q id='wrMTu'></q></dir></style></legend>

        为什么在函数上使用函子?

        时间:2024-05-12
            <tbody id='2xRWC'></tbody>

            • <i id='2xRWC'><tr id='2xRWC'><dt id='2xRWC'><q id='2xRWC'><span id='2xRWC'><b id='2xRWC'><form id='2xRWC'><ins id='2xRWC'></ins><ul id='2xRWC'></ul><sub id='2xRWC'></sub></form><legend id='2xRWC'></legend><bdo id='2xRWC'><pre id='2xRWC'><center id='2xRWC'></center></pre></bdo></b><th id='2xRWC'></th></span></q></dt></tr></i><div id='2xRWC'><tfoot id='2xRWC'></tfoot><dl id='2xRWC'><fieldset id='2xRWC'></fieldset></dl></div>
              <tfoot id='2xRWC'></tfoot>
            • <legend id='2xRWC'><style id='2xRWC'><dir id='2xRWC'><q id='2xRWC'></q></dir></style></legend>

              <small id='2xRWC'></small><noframes id='2xRWC'>

                <bdo id='2xRWC'></bdo><ul id='2xRWC'></ul>

                1. 本文介绍了为什么在函数上使用函子?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着跟版网的小编来一起学习吧!

                  问题描述

                  比较

                  double average = CalculateAverage(values.begin(), values.end());
                  

                  double average = std::for_each(values.begin(), values.end(), CalculateAverage());
                  

                  在函数上使用函子有什么好处?第一个是不是更容易阅读(甚至在添加实现之前)?

                  What are the benefits of using a functor over a function? Isn't the first a lot easier to read (even before the implementation is added)?

                  假设函子定义如下:

                  class CalculateAverage
                  {
                  private:
                     std::size_t num;
                     double sum;
                  public:
                  
                     CalculateAverage() : num (0) , sum (0)
                     {
                     }
                  
                     void operator () (double elem) 
                     {
                        num++; 
                        sum += elem;
                     }
                  
                     operator double() const
                     {
                         return sum / num;
                     }
                  };
                  

                  推荐答案

                  至少有四个很好的理由:

                  At least four good reasons:

                  关注点分离

                  在您的特定示例中,基于函子的方法具有将迭代逻辑与平均计算逻辑分离的优点.因此,您可以在其他情况下使用您的函子(想想 STL 中的所有其他算法),并且您可以将其他函子与 for_each 一起使用.

                  In your particular example, the functor-based approach has the advantage of separating the iteration logic from the average-calculation logic. So you can use your functor in other situations (think about all the other algorithms in the STL), and you can use other functors with for_each.

                  参数化

                  您可以更轻松地参数化函子.因此,例如,您可以有一个 CalculateAverageOfPowers 函子,它取数据的平方或立方体等的平均值,可以这样写:

                  You can parameterise a functor more easily. So for instance, you could have a CalculateAverageOfPowers functor that takes the average of the squares, or cubes, etc. of your data, which would be written thus:

                  class CalculateAverageOfPowers
                  {
                  public:
                      CalculateAverageOfPowers(float p) : acc(0), n(0), p(p) {}
                      void operator() (float x) { acc += pow(x, p); n++; }
                      float getAverage() const { return acc / n; }
                  private:
                      float acc;
                      int   n;
                      float p;
                  };
                  

                  你当然可以用传统函数做同样的事情,但这样就很难与函数指针一起使用,因为它有一个与CalculateAverage不同的原型.

                  You could of course do the same thing with a traditional function, but then makes it difficult to use with function pointers, because it has a different prototype to CalculateAverage.

                  状态

                  由于函子可以是有状态的,你可以这样做:

                  And as functors can be stateful, you could do something like this:

                  CalculateAverage avg;
                  avg = std::for_each(dataA.begin(), dataA.end(), avg);
                  avg = std::for_each(dataB.begin(), dataB.end(), avg);
                  avg = std::for_each(dataC.begin(), dataC.end(), avg);
                  

                  对多个不同的数据集求平均值.

                  to average across a number of different data-sets.

                  请注意,几乎所有接受函子的 STL 算法/容器都要求它们是纯"谓词,即随着时间的推移没有可观察到的状态变化.for_each 是这方面的一个特例(参见例如 Effective Standard C++ Library - for_each vs. transforma>).

                  Note that almost all STL algorithms/containers that accept functors require them to be "pure" predicates, i.e. have no observable change in state over time. for_each is a special case in this regard (see e.g. Effective Standard C++ Library - for_each vs. transform).

                  性能

                  函数通常可以被编译器内联(毕竟 STL 是一堆模板).虽然理论上函数也是如此,但编译器通常不会通过函数指针内联.典型的例子是比较 std::sortqsort;假设比较谓词本身很简单,STL 版本通常要快 5-10 倍.

                  Functors can often be inlined by the compiler (the STL is a bunch of templates, after all). Whilst the same is theoretically true of functions, compilers typically won't inline through a function pointer. The canonical example is to compare std::sort vs qsort; the STL version is often 5-10x faster, assuming the comparison predicate itself is simple.

                  总结

                  当然,可以使用传统的函数和指针来模拟前三个,但使用函子会变得更加简单.

                  Of course, it's possible to emulate the first three with traditional functions and pointers, but it becomes a great deal simpler with functors.

                  这篇关于为什么在函数上使用函子?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!

                  上一篇:如何重用 ostringstream? 下一篇:为什么 std::vector 和 std::array 的 C++ initializer_list 行为不同?

                  相关文章

                  <legend id='0w1mj'><style id='0w1mj'><dir id='0w1mj'><q id='0w1mj'></q></dir></style></legend>

                  1. <tfoot id='0w1mj'></tfoot>

                    <small id='0w1mj'></small><noframes id='0w1mj'>

                      <bdo id='0w1mj'></bdo><ul id='0w1mj'></ul>

                      <i id='0w1mj'><tr id='0w1mj'><dt id='0w1mj'><q id='0w1mj'><span id='0w1mj'><b id='0w1mj'><form id='0w1mj'><ins id='0w1mj'></ins><ul id='0w1mj'></ul><sub id='0w1mj'></sub></form><legend id='0w1mj'></legend><bdo id='0w1mj'><pre id='0w1mj'><center id='0w1mj'></center></pre></bdo></b><th id='0w1mj'></th></span></q></dt></tr></i><div id='0w1mj'><tfoot id='0w1mj'></tfoot><dl id='0w1mj'><fieldset id='0w1mj'></fieldset></dl></div>