【问题标题】:vector iterators incompatible error矢量迭代器不兼容错误
【发布时间】:2011-08-11 09:36:06
【问题描述】:

我在运行时遇到向量迭代器不兼容错误。它发生在代码部分的最后,在 for 循环内 (humans.push_back( Human(&deck, (*iter)) );) 当我第一次收到错误时,我错误地使用了与“iter”不同的迭代器,所以运行时错误完全有道理。但是现在我更改了它并重新编译了所有内容(我仔细检查了它),我仍然得到这个错误。

void BlackjackGame::getHumansAndHouse()
{
    // asks how many players, pushes_back vector accordingly, initializes house, checking for valid input throughout
    string input;
    vector<string> names;
    while(true)
    {
        cout << "How many humans? (1 - 7)" << endl;
        cin >> input;
        if(!isdigit(input[0]))
            cout << "Invalid input. ";
        else
        {
            input.erase(1);
            int j = atoi(input.c_str());
            for(int i = 1; i <= j; i++)
            {
                while(true)
                {
                    cout << "Enter player " << i << " name: ";
                    cin >> input;
                    if(strcmp(input.c_str(), "House") == 0)
                        cout << "Player name has to be different than 'House'." << endl;
                    else
                    {
                        names.push_back(input);
                        break;
                    }
                }
            }
            break;
        }
    }
    vector<string>::iterator iter;
    for(iter = names.begin(); iter != names.end(); iter++)
        humans.push_back( Human(&deck, (*iter)) );

    house = House(&deck);
}

人类是一个向量:

vector<Human> humans;

其中 Human 是一个类,其构造函数如下:

Human(Deck *d, string n) : Player(d), name(n) { printNameCardsAndTotal(); }

(Human是Player的派生类)

由于 iter 是字符串向量的迭代器,我不明白为什么我在 for 循环内的那一行中得到向量迭代器不兼容。这不像是我试图直接对人类使用 iter。

错误在这里:

humans.push_back( Human(&deck, (*iter)) );

【问题讨论】:

  • 能否请您发布定义nameshumans 向量的代码,以及实际的错误输出?
  • names' 迭代器位于我的代码之上,为了清晰起见,我将其移至底部。实际的向量名称位于代码部分的顶部。我也发布了人类。
  • deck 声明在哪里?
  • 好的,我现在看到了向量和迭代器的定义,很抱歉。编译器或运行时输出(错误消息,直接从终端复制并粘贴到代码框格式)怎么样?
  • 请提供一个独立的示例。 “自包含”表示源代码用于编译和执行,除了标准库之外没有任何依赖。

标签: c++ vector runtime-error


【解决方案1】:

错误出现在您未显示的代码中。以下代码是我根据您的代码和您的描述编写的,不会产生任何错误:

#include <vector>
#include <string>
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cctype>

using namespace std;

class Deck
{
};

class Player()
{
  public:
    Player(Deck *d) {}
};

class Human : public Player
{
  public:
    Human(Deck *d, string n) : Player(d), name(n) {}
  private:
    string name;
};

class House
{
  public:
    House(Deck *d) {}
};

int main()
{
    Deck deck;
    vector<Human> humans;
    string input;
    vector<string> names;
    while(true)
    {
        cout << "How many humans? (1 - 7)" << endl;
        cin >> input;
        if(!isdigit(input[0]))
            cout << "Invalid input. ";
        else
        {
            input.erase(1);
            int j = atoi(input.c_str());
            for(int i = 1; i <= j; i++)
            {
                while(true)
                {
                    cout << "Enter player " << i << " name: ";
                    cin >> input;
                    if(strcmp(input.c_str(), "House") == 0)
                        cout << "Player name has to be different than 'House'." << endl;
                    else
                    {
                        names.push_back(input);
                        break;
                    }
                }
            }
            break;
        }
    }
    vector<string>::iterator iter;
    for(iter = names.begin(); iter != names.end(); iter++)
        humans.push_back( Human(&deck, (*iter)) );

    House house = House(&deck);
    return 0;
}

【讨论】:

    【解决方案2】:

    不如试试

    iter != names.end()
    

    【讨论】:

    • 感谢您的回答,但错误在下一行! (我试过以防万一,它不能解决问题)。顺便说一句,使用 != 更快吗?
    • @Edoz:std::vector 可能没有什么不同。 std::vector 具有随机访问迭代器,因此使用 &lt; 非常好。
    【解决方案3】:

    始终在 for 循环中预先增加迭代器并使用 it != end 作为 C++ 中的标记(这也适用于 ints。

    for(iter = names.begin(); iter **!=** names.end(); **++iter**)
    

    【讨论】:

    • ++iter 与 iter++ 不同吗?反正我试过了,还是不行
    • 请注意,错误在 for 循环内部,而不是在它的“声明”中(我检查了断点)
    • 是的 ++iter 是不同的,但在这里应该没什么区别。试试for(iter = names.begin(); iter != names.end(); iter++) humans.push_back( Human(&amp;deck, string("foo") );,看看它是否有效,如果有效,那么你就知道iter 有问题。
    • 感谢您的提示,是的,我仍然使用 'foo' 得到错误。这意味着问题不是迭代!但是为什么我会得到一个迭代器错误?
    • 首先对于迭代器,它总是更有效,因为它避免了复制迭代器(对于int 类型没有性能提升)。其次,如果您养成对所有数据类型始终使用它的习惯(除非您明确需要后增量),那么您将不假思索地免费优化您的代码。这只是一个好习惯。此外,如果您总是在 for 循环中使用 !=,那么您可以在 intiterator 之间无缝切换,而无需更改任何语法。 (可能是Effective C++,不记得了)
    【解决方案4】:

    Microsoft &lt;vector&gt; 标头实现在您的构建中启用了一些调试检查,这使得迭代器比单纯的指针更丰富的对象 - 它们跟踪它们正在迭代的容器及其“邻居”迭代器以及对象他们指向。您遇到的断言是检查应该指向同一个容器的 2 个迭代器,但发现它们没有(根据迭代器的状态)。

    因此,您要么在某处损坏了迭代器对象/列表,要么正在执行代码 sn-ps 中未显示的操作。

    【讨论】:

      猜你喜欢
      • 2012-04-17
      • 1970-01-01
      • 1970-01-01
      • 2013-02-10
      • 1970-01-01
      • 2012-01-15
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多