【问题标题】:erase function in a vector向量中的擦除函数
【发布时间】:2012-01-15 12:24:22
【问题描述】:

我正在努力学习 C++。这段代码在没有 delSong 函数的情况下编译得很好。但是有了它,它不会编译。而且我无法弄清楚我做错了什么......:-/

#include <iostream>
#include <vector>
#include <string>

using namespace std;

class Jukebox {

public:
  void addSong(string artist, string title, string filename) {
    songCounter++;
    song s {songCounter, artist, title, filename};
    Songs.push_back(s);
  }

  void delSong(int pos) {
    Songs.erase(pos);
  }

  void printSong(int pos) {
    cout << Songs[pos].no << ". ";
    cout << Songs[pos].artist << " - ";
    cout << Songs[pos].title << " : ";
    cout << Songs[pos].filename << endl;
  }

  void printSongs() {
    for (int i = 0; i < Songs.size(); i++) {
      printSong(i);
    }
  }

  Jukebox(): songCounter(0) {}

private:
  int songCounter;
  struct song {
    int no;
    string artist;
    string title;
    string filename;
  };
  vector<song> Songs;
};

int main() {
  Jukebox jbox;
  jbox.addSong("U2", "Magnificent", "U2-Magnificent.mp3");
  jbox.addSong("Sting", "Englishman in New York", "Sting-Englishman_in_New_York.mp3");
  jbox.addSong("U2", "One", "U2-One.mp3");
  jbox.printSongs();
  return 0;
}

【问题讨论】:

  • 给我们你得到的编译器错误。
  • 对不起。它不会编译。我可以编辑问题来解决它。但是我的另一个新手问题是 g++ 以瑞典语输出错误消息。所以如果我应该显示错误消息,我必须找到一些语言环境设置。
  • 嘿,我想学瑞典语! :D 顺便说一句,你可以尝试在ideone.com 上编译,它在那里有一个语言环境。
  • @NiclasNilsson:这与您的问题没有直接关系,但是:在 C++ 中,最好通过 const 引用而不是值来传递字符串类实例的输入参数(它更有效,并且避免了复制构造函数调用),因此您可能希望像这样更新您的方法:“void addSong(const string & artist, const string & title, const string & filename)”。
  • @NiclasNilsson:按引用传递 (&) 就像按指针传递(在语义上),但语法是按值传递。正如您已经阅读的那样,如果您通过引用传递 - 因为您实际上是在传递一个指针 - 可以修改指向的变量。考虑到在您的情况下,参数是输入参数(即只读),我建议使用“const”说明符,因此:通过 const 引用传递(const std::string &)。通过 const 引用传递不允许修改变量('const'),同时与通过指针(reference/'&')传递一样高效。

标签: c++ vector


【解决方案1】:

看看erase是如何定义的:

http://www.cplusplus.com/reference/stl/vector/erase/

iterator erase ( iterator position );
iterator erase ( iterator first, iterator last );

它将迭代器,而不是索引,作为参数。所以不是

Songs.erase(5);

尝试:

Songs.erase(Songs.begin() + 5);

begin() 返回一个迭代器,+5 将它移动到要删除的位置。

【讨论】:

  • +1 供参考。所有刚接触编程语言的人都需要知道在哪里查找资料。
【解决方案2】:

std::vector&lt;T&gt;::erase() 函数不需要索引。它需要一个迭代器。如果您想从带有随机访问容器的索引中获取迭代器(例如 std::vector&lt;T&gt;),您可以使用 begin() 并添加相应的偏移量:

this->Songs.erase(this->Songs.begin() + pos);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-17
    • 1970-01-01
    • 2017-05-18
    • 1970-01-01
    • 1970-01-01
    • 2021-03-05
    相关资源
    最近更新 更多