免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1812 | 回复: 4
打印 上一主题 下一主题

[C++] 请教一个STL的问题! [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2011-03-15 21:13 |只看该作者 |倒序浏览
本帖最后由 xiaozhi7566 于 2011-03-15 21:15 编辑

刚刚接触STL,今天看到一个例子,25行那句代码不懂,请帮忙解释一下,谢谢!

  1. #include <iterator>
  2. #include <iostream>
  3. #include <algorithm>   // Need random_shuffle()
  4. #include <vector>      // Need vector
  5. #include <functional> // Need unary_function
  6. using namespace std; // Data to randomize
  7. int iarray[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
  8. vector<int> v(iarray, iarray + 10); // Function prototype
  9. void Display(vector<int>& vr, const char *s); // The FiboRand template function-object class
  10. template <class Arg>
  11. class FiboRand : public unary_function<Arg, Arg>
  12. {
  13.         int i, j;
  14.         Arg sequence[18];
  15. public:
  16.         FiboRand();
  17.         Arg operator()(const Arg& arg);
  18. };
  19. void main()
  20. {
  21.         FiboRand<int> fibogen; // Construct generator object
  22.         cout << "Fibonacci random number generator" << endl;
  23.         cout << "using random_shuffle and a function object" << endl;
  24.         Display(v, "Before shuffle:");
  25.         random_shuffle(v.begin(), v.end(), fibogen); //这里为什么会调用 Arg FiboRand<Arg>::operator()(const Arg& arg)这个函数?     
  26.       Display(v, "After shuffle:");
  27.         system("pause");
  28. } // Display contents of vector vr
  29. void Display(vector<int>& vr, const char *s)
  30. {
  31.         cout << endl << s << endl;
  32.         copy(vr.begin(), vr.end(),ostream_iterator<int>(cout, " "));
  33.         cout << endl;
  34. } // FiboRand class constructor
  35. template<class Arg>
  36. FiboRand<Arg>::FiboRand()
  37. {
  38.         sequence[17] = 1;
  39.         sequence[16] = 2;
  40.         for (int n = 15; n >=0; n--)   
  41.                 sequence[n] = sequence[n + 1] + sequence[n + 2];
  42.         i = 17;
  43.         j = 5;
  44. } // FiboRand class function operator

  45. template<class Arg>
  46. Arg FiboRand<Arg>::operator()(const Arg& arg)
  47. {
  48.         Arg k = sequence[i] + sequence[j];
  49.         sequence[i] = k; i--;
  50.         j--;
  51.         if (i == 0)
  52.                 i = 17;
  53.         if (j == 0)
  54.                 j = 17;
  55.         return k % arg;
  56. }
复制代码

论坛徽章:
1
射手座
日期:2013-08-21 13:11:46
2 [报告]
发表于 2011-03-15 23:28 |只看该作者

  1. template<class _RanIt,
  2.         class _Fn1> inline
  3.         void random_shuffle(_RanIt _First, _RanIt _Last, _Fn1& _Func)
  4.         {        // shuffle [_First, _Last) using random function _Func
  5.         _DEBUG_RANGE(_First, _Last);
  6.         _DEBUG_POINTER(_Func);
  7.         if (_First != _Last)
  8.                 _Random_shuffle(_Unchecked(_First), _Unchecked(_Last), _Func,  //调用下面那个函数
  9.                         _Dist_type(_First));
  10.         }
  11. template<class _RanIt,
  12.         class _Fn1,
  13.         class _Diff> inline
  14.         void _Random_shuffle(_RanIt _First, _RanIt _Last, _Fn1& _Func, _Diff *)
  15.         {        // shuffle nonempty [_First, _Last) using random function _Func
  16.         _RanIt _Next = _First;
  17.         for (_Diff _Index = 2; ++_Next != _Last; ++_Index)
  18.                 _STD iter_swap(_Next, _First + _Diff(_Func(_Index) % _Index)); //_Func需要有一个传入参数
  19.         }
复制代码
然后你的:
FiboRand<int> fibogen;
fibogen对象会有一个
int operator()(const int& arg); 这样的函数,就是那个_Func(_Index)

论坛徽章:
0
3 [报告]
发表于 2011-03-16 00:55 |只看该作者
回复 2# egmkang


    为什么传入的是fibogen对象的operator()(const Arg& arg)函数,我给FiboRand加了一个类似的成员函数,然后把operator函数去掉,就会报错。为什么不调用新加一个函数?这个'()'运算符重载函数是什么意思?

论坛徽章:
1
射手座
日期:2013-08-21 13:11:46
4 [报告]
发表于 2011-03-16 01:20 |只看该作者
本帖最后由 egmkang 于 2011-03-16 10:51 编辑

FiboRand<int> fibogen;
fibogen(10); 你这个函数调用就跟,这个调用的就是operator()函数.
而这个random_shuffle他就调用_Func对象的()函数..

你要是想让他调用其他的函数,就需要自己去实现random_shuffle了
有兴趣你可以看STL源码,自己实现一个

PS:
你如果给FiboRand实现一个Function(Arg&)函数的话,那么random_shuffle里面的代码就变成了:

template<class _RanIt,
        class _Fn1,
        class _Diff> inline
        void _Random_shuffle(_RanIt _First, _RanIt _Last, _Fn1& _Func, _Diff *)
        {        // shuffle nonempty [_First, _Last) using random function _Func
        _RanIt _Next = _First;
        for (_Diff _Index = 2; ++_Next != _Last; ++_Index)
                _STD iter_swap(_Next, _First + _Diff(_Func.Function(_Index) % _Index));
}
希望你对比一下原先的实现,再看看这个

论坛徽章:
0
5 [报告]
发表于 2011-03-16 15:46 |只看该作者
回复 2# egmkang


    听君一席话,豁然开朗!十分感谢!
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP