error 2625实现STL的copy算法时出现的问题

Posted Harley_Quinn

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了error 2625实现STL的copy算法时出现的问题相关的知识,希望对你有一定的参考价值。

在实现set_union算法时调用了自己写的copy算法,出现了以下问题。

Error 1 error C2665: ‘xyz_stl::__copy‘ : none of the 2 overloads could convert all the argument types 

即“__copy的2个重载不能转换所有的参数类型”。

注:__copy是照着STL源码剖析进行命名的(实际上我倒很不喜欢SGI的那么长的命名),是针对输入迭代器(InputIterator)的迭代器类型(iterator_category)进行两个分支,如果仅仅是普通的输入迭代器,就采用迭代器比较(first != last)的方式判断是否到达末尾,如果是随机访问迭代器(RandomAccessIterator),则用一个int来递减通过判断该int是否大于0来判断是否到达末尾。

看看错误信息的输出

e:\code\数据结构\stl_algo\stl_algo\stl_algo.h(230): could be ‘OutputIterator xyz_stl::__copy<InputIterator,OutputIterator>(RandomAccessIterator,RandomAccessIterator,OutputIterator,std::random_access_iterator_tag)‘
1> with
1> [
1> OutputIterator=std::ostream_iterator<int,char,std::char_traits<char>>
1> , InputIterator=std::_Tree_const_iterator<std::_Tree_val<std::_Tree_simple_types<int>>>
1> , RandomAccessIterator=std::_Tree_const_iterator<std::_Tree_val<std::_Tree_simple_types<int>>>
1> ]
1> e:\code\数据结构\stl_algo\stl_algo\stl_algo.h(220): or ‘OutputIterator xyz_stl::__copy<InputIterator,OutputIterator>(InputIterator,InputIterator,OutputIterator,std::input_iterator_tag)‘
1> with
1> [
1> OutputIterator=std::ostream_iterator<int,char,std::char_traits<char>>
1> , InputIterator=std::_Tree_const_iterator<std::_Tree_val<std::_Tree_simple_types<int>>>
1> ]

  

相当于给出了更详细的说明,但是这个说明我没理解清楚(因为太长了没仔细看),对我的调试产生了很严重的误导……

我以为是“既可能匹配到input_iterator_tag也可能匹配到random_access_iterator_tag,分别给出了这两种情况下的模板参数”。然后就很混乱,甚至想出了用个函数返回iterator_category*来进行强制转换,虽然这样改了后编译通过,但是根据之前写distance的经验,并不需要这么做,只有对value_type等其他几个迭代器属性时才需要返回指针。

PS:这段出错信息就可以看出来我的输入迭代器是std::set的迭代器(树常迭代器),输出迭代器是输出流迭代器,模板的名字太长orz

后来仔细查看调用__copy函数的代码

    OutputIterator operator()(InputIterator first, InputIterator last,
        OutputIterator result)
    {
        typedef typename
            std::iterator_traits<OutputIterator>::iterator_category
            iter_category;
        return __copy(first, last, result, iter_category());
    }

在一堆长长的名字里找bug真是得看眼力orz问题出在iter_category是取得输出迭代器)的迭代器类型,而这里的输出迭代器是ostream_iterator,它继承自类_Outit(微软STL中),而这个类的定义如下

// base for output iterators
typedef iterator<output_iterator_tag, void, void, void, void> _Outit;

迭代器类型是output_iterator_tag,由于我只对input_iterator_tag和random_access_iterator_tag进行了“强化”(就是编译期的if语句),所以无法找到匹配这种迭代器类型的函数模板。实际上也不能为输出迭代器写copy,这种情况只会出现在代码错误的时候,比如我这里。

 

那么回到出错信息,后面还有一段

while trying to match the argument list ... with ... with ...

而前面那一段错误信息实际上是 could be ... with ... with ...

也就是在尝试匹配参数列表时遇到了问题,不是可能匹配两种模板,而是在匹配这两种模板时出了问题,编译器提示说重载个数不够。

 

其实还有个一直疑问的问题,那就是我在实现跟STL一模一样的名字时,我用了自己的命名空间xyz_stl,但是在命名空间内部如果直接调用该函数时会出现错误信息 

error C2668: ‘xyz_stl::copy‘ : ambiguous call to overloaded function

我之前百思不得其解,明明没有使用using namespace std来污染命名空间,为什么会出现有歧义的调用呢?

后来想起来了,函数模板是在用确定类型调用它时才实例化

而我在调用这个函数模板时,该cpp文件使用了using namespace std;而且函数模板是直接声明为inline的,也就是像宏一样直接展开代码。

虽然还是理解不太清楚,但是大概就是这两个原因吧- -

以上是关于error 2625实现STL的copy算法时出现的问题的主要内容,如果未能解决你的问题,请参考以下文章

Redshift UNLOAD COPY 失败数据损坏 stl_load_errors MAXFILESIZE

Redshift COPY 抛出错误,但“stl_load_errors”系统表未提供详细信息

Redshift COPY 命令返回 stl_load_error 1205 无效的日期格式 - 长度必须为 10 或更多

STL算法之函数copy

在 random_shuffle() 对象向量时出现很多错误?

STL源代码剖析——基本算法stl_algobase.h