C ++中向量的奇怪错误

时间:2018-01-14 02:25:58

标签: c++ visual-studio vector directx

每次编译我正在处理的RTS项目的代码时,都会收到此错误:

error C2664: 'std::_Vector_iterator<_Ty,_Alloc> std::vector<_Ty>::erase(std::_Vector_const_iterator<_Ty,_Alloc>)' : cannot convert parameter 1 from 'MAPTILE *' to 'std::_Vector_const_iterator<_Ty,_Alloc>'

我对此方法的代码区域是:

MAPTILE *startTile = GetTile(start);
    MAPTILE *goalTile = GetTile(goal);

...

    std::vector<MAPTILE*> open;             //Create Our Open list
    startTile->g = 0;                       //Init our starting point (SP)
    startTile->f = H(start, goal);
    startTile->open = true;
    open.push_back(startTile);              //Add SP to the Open list

    bool found = false;                  // Search as long as a path hasnt been found,
    while(!found && !open.empty())       // or there is no more tiles to search
    {                                               
        MAPTILE * best = open[0];        // Find the best tile (i.e. the lowest F value)
        int bestPlace = 0;
        for(int i=1;i<open.size();i++)
            if(open[i]->f < best->f)
            {
                best = open[i];
                bestPlace = i;
            }

        if(best == NULL)break;          //No path found

        open[bestPlace]->open = false;
        open.erase(&open[bestPlace]);   // Take the best node out of the Open list

我在这个网站和其他几个网站上搜索过,但找不到正确的区域。

我正在阅读“使用Direct3D编写RTS游戏”作者:Carl Granberg。

我的所有代码都是正确的,因为我将它与源代码匹配,我得到了同样的错误。

我使用的是Visual C ++ 2008 Express Edition。

我之前从未收到此错误。

1 个答案:

答案 0 :(得分:2)

erase想要一个迭代器,你给它一个指向数组中元素的指针。使用std::advance或保留迭代器的句柄。

std::vector<MAPTILE*> p = open.begin();
std::advance(p, bestPlace);
open.erase(p);

编辑 我忘了std::advance没有返回任何内容。对于那个很抱歉。我大约五年没有做过严肃的C ++开发。

我会重写你的for循环来使用迭代器而不是索引。

我相信在使用迭代器替换数组索引之后,以下代码段相当于您的代码段。我必须添加typedef以使其更具可读性。

    MAPTILE *startTile = GetTile(0);
    startTile->g = 0;
    startTile->f = H(0, 10);
    startTile->open = true;

    std::vector<MAPTILE*> open;
    open.push_back(startTile);

    typedef std::vector<MAPTILE*>::iterator Iterator;
    bool found = false;
    while (!found && !open.empty()) {
            Iterator best = open.begin();
            for (Iterator iter=best+1, end=open.end();
                 iter!=end; ++iter)
            {
                    if ((*iter)->f < (*best)->f) {
                            best = iter;
                    }
            }
            if (*best == NULL) {
                    break;
            }
            (*best)->open = false;
            open.erase(best);
    }

我并不完全相信if (*best == NULL)条件会匹配。这在clang++下编译没有错误(抱歉,我家里没有视觉工作室)。当我通过clang++运行您的代码段时,我会遇到类似的失败:

foo.cpp:85:14: error: calling a private constructor of class
      'std::__1::__wrap_iter<MAPTILE *const *>'
                open.erase(&open[bestPlace]);
                           ^
    /Library/Developer/CommandLineTools/usr/include/c++/v1/iterator:1381:31: note:
      declared private here
    _LIBCPP_INLINE_VISIBILITY __wrap_iter(iterator_type __x) _NOEXCEPT_D...
                              ^
1 error generated.

我不知道还有什么要说的,std::vector<>::erase需要一个std::vector<>::iterator参数,而这就是它的全部内容。我的猜测是,这本书是针对使用指向矢量迭代器的VC ++版本编写的,尽管我不记得那个曾经做过的人。