3

我正在尝试开始使用 C++,并且应该实现以下功能:

std::istream& readResults(std::istream& is, std::back_insert_iterator<std::vector<Result>> insertIt)

该函数从 istream 读取格式为“studentId Grade”的行,并应使用 insertIt 将它们添加到向量类型。

结果是一个结构:

struct Result
{
  std::string studentId;
  size_t grade;
};

你能给我一个关于如何开始的提示吗?

我尝试过这样的事情:

std::string studentId;
size_t grade;
Result new_result;

while(is >> studentId >> grade) {
    Result new_result = {studentId, grade};
    copy(new_result, *insertIt);
    }
4

3 回答 3

4

您不想实现该功能

std::istream& readResults(
    std::istream& is,
    std::back_insert_iterator<std::vector<Result>> insertIt)

你想要做的是实现模板功能

template<class InsertIterator>
std::istream& readResults(std::istream& is, InsertIterator insertIt)

当您通过std::back_inserter(vec)时,模板将自动实例化为正确的类型。

这个函数的代码基本上是

template<class InsertIterator>
std::istream& readResults(std::istream& is, InsertIterator insertIt) {
  std::string studentId;
  size_t grade;
  while (is >> studentId >> grade) {
    Result new_result = {studentId, grade};
    *(insertIt++) = new_result;
  }
}

std::copy从一个迭代器复制到另一个。但是您不是从迭代器中复制。你一次插入一个元素,你通过取消引用迭代器来做到这一点,就好像它是一个指针,然后在你完成后递增它。

于 2012-09-23T22:17:12.027 回答
3

std::back_insert_iterator 直接使用真的很麻烦。请改用模板函数 std::back_inserter (它会为您完成所有模板参数推断)。

你的 readResults 会变成这样:

std::copy(std::istream_iterator<Result>(is), std::istream_iterator<Result>(), std::back_inserter(v));

前提是您为 Result 重载了 operator>>。

于 2012-09-23T21:31:58.097 回答
1

您想为您的Result, 即声明如下的内容创建一个读取函数:

std::istream& operator>> (std::istream& in, Result& result)
{
    // read your result here
    return in;
}

有了这个,实现readResult()变得相当简单:

std::copy(std::istream_iterator<Result>(is), std::istream_iterator<Result>(), insertIt);

除此之外,您只需要readResult()使用合适的迭代器调用您的函数。

于 2012-09-23T21:29:06.753 回答