1. whoops... something weird
事情的起因是在《STL源码剖析》中看到了这样一个函数:
2 iterator j = i;
3 ++j;
4 if (position == i || position == j) return;
5 transfer(position, i, j);
6 }
简洁、清晰,唯一令我困惑的是list&的作用:它显然没什么作用。
2. anonymous formal parameter
不管怎样,list&是一个无名形参,这一点不会错。那就想想什么样的情况下会用无名形参。
Type& operator++ (int);
这是一种情况:为了触发重载。更一般地,如果函数的行为只取决于参数的类型,那么就可以书写无名形参以使代码干净整洁。不过即使回忆起这一点,splice的list&也还是很怪异,尤其是考虑到splice乃list类的成员函数,若说list&还有可能被换成vector&,那是没道理的。
考虑另一种可能。
2 return fptr(x, y);
3 }
这是有意设计的一个函数,其第三个参数是函数指针,典型的被指函数可能有求和、求差等等,但也可能需要这样的操作:求y的平方。为了能被fptr指向,某个平方函数就必须这样定义:
函数指针一说虽然仍不能直接解释splice的list&,但已接近答案了。
3、at last...
函数指针实际上是规定了一套标准,所有的被指函数都应当符合这一标准,只不过ySquare认为x参数没什么用。
STL也是规定了一套标准,所有的STL实现版本都应当符合这一标准,只不过SGI的实现版本认为splice的list&参数没什么用。事情最终就是这么简单。
查阅了C++标准(ISO/IEC 14882:2003(E)),人家这么写:
void splice (iterator position, list<T, Allocator>& x, iterator i);
Effects: Inserts an element pointed to by i from list x before position and removes the element from x. The result is unchanged if position == i or position == ++i. Invalidates only the iterators and references to the spliced element.
Throws: Nothing.
Requires: i is a valid dereferenceable iterator of x.
Complexity: Constant time.
两下一对比可以得出结论:SGI的splice默认i所在的list为x,可算完美地遵循了标准。
4、conclusion
最基本的事实最容易忘记。
盯着极小的局部看问题,那样的困惑是井底之蛙的困惑。
5、new problem
splice中的list&为什么存在?因为是标准规定的。可其实我关心的是标准为什么要这么定。要满足这个好奇心就需要把各个实现版本的STL拿来比一比,到时候自然各有各的道理。
一个问题的解决总是带来更多的问题。有空再说吧。