第一个问题是函数不能拥有默认模板参数类型。一般容器都提供了默认模板参数类型,比如 vector
就是省略了 allocator。《C++ STL 中文版》第 300 页可以看到如此声明:
template <class T, class Ax = allocator<T> >
class vector;
|
模板参数 Ax 后面的 allocator 就是默认模板参数类型了。
今天在一个泛型函数时,开始写成这样了:
template <typename Iter, typename Comp = less<typename iterator_traits<Iter>::value_type> >
void
__sort_combination (Iter first, Iter last, Comp comp = Comp());
|
结果编译时出错,g++ 的错误提示没看明白,看了 VC7.1 错误提示才知道原因是函数不能拥有默认模板参数类型。这让我想起,g++ 使用的 STL 中 的函数,如果有基于小于的比较和谓词两个版本的话,其中一个是直接以 < 比较的没有谓词模板参数的版本,另一个带谓词的但是没有默认模板参数类型的谓词版本。
最后改成这样:
template <typename Iter>
void
__sort_combination (Iter first, Iter last);
template <typename Iter, typename Comp>
void
__sort_combination (Iter first, Iter last, Comp comp);
|
至于普通版本的内部是否调用谓词版本来实现,那就任意了。
今天碰到的第二个问题是语义上的问题。还是上面的 __sort_combination,它有两个正交的可选项,缓冲区和谓词,因此正交后有四种函数声明:
template <typename Iter>
void
__sort_combination (Iter first, Iter last);
template <typename Iter, typename BufferIter>
void
__sort_combination (Iter first, Iter last, BufferIter buffer);
template <typename Iter, typename Comp>
void
__sort_combination (Iter first, Iter last, Comp comp);
template <typename Iter, typename BufferIter, typename Comp>
void
__sort_combination (Iter first, Iter last, BufferIter buffer, Comp comp);
|
问题就出在第二与第三个声明上。虽然我们可以很清楚的知道 BufferIter 与 Comp 两个参数的不同,一个是 iterator,用作缓冲区,另一个是谓词,用于比较大小。然而对于编译器来说,两者并“没有”区别,就像萧峰与乔峰一样,所以产生冲突。
最后只有舍弃第二个版本。
其他的一些问题,主要是围绕谓词版本产生的。一天下来对于谓词有了更深的理解,也发现对于泛型,我不知道的还有很多……
阅读(3475) | 评论(0) | 转发(0) |