c++ - 什么是插入列表 map 的正确方法

标签 c++ stl

我正在用 C++ 创建索引器应用程序。 目录的文本文件中的每个唯一单词,我想像这样存储- first_map<"word", second_map<"File Object reference", List{line numbers}>

为了第一次填充这张 map ,我逐字解析目录中的每个文件。为了将数据推送到 map 中,我在使用 like- 时遇到编译错误-

pool[token][it].push_back(count);  

如果内部映射值是 int 类型,我认为这不会引发错误。 我也尝试使用 like-

pool[token].insert(std::make_pair(it, count);

这也因错误而失败。 将数据插入此容器的正确方法是什么?

完整的源代码如下-

#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <stdlib.h>
#include <dirent.h>
#include <errno.h>
#include <string.h>
#include<iostream>
#include<iterator>
#include<algorithm>
#include<string>
#include<sstream>
#include<list>
#include<vector>
#include<fstream>
#include<map>
#include<ctime>

class File {
  public:
    std::string file_name;
    int timestamp;
    File(std::string name) : file_name(name) {
      struct stat st;
      int ierr = stat (file_name.c_str(), &st);
      if (ierr != 0) {
        std::cout << "error in getting timestamp";
      }
      timestamp = st.st_mtime;
    }
};

class Location {
  public:
    std::vector<File> indexer;
    virtual std::map<File*, std::list<int> > find_pattern(std::string& word);
    Location(const char* in_dir){
      DIR* FD;
      struct dirent* in_file;
      /* Scanning the in directory */
      if (NULL == (FD = opendir (in_dir)))
      {
        fprintf(stderr, "Error : Failed to open input directory - %s\n", strerror(errno));
        throw -1;
      }
      while ((in_file = readdir(FD)))
      {
        if (!strcmp (in_file->d_name, "."))
          continue;
        if (!strcmp (in_file->d_name, ".."))
          continue;
        indexer.push_back(File(in_file->d_name));

      }
    }
};
class TextFileLocation : public Location {
  public:
    std::map<std::string, std::map<File*, std::list<int> > > pool;
    TextFileLocation(const char* in_dir) : Location(in_dir){

      for(auto it = indexer.begin(); it != indexer.end(); it++){
        std::ifstream file1(it->file_name);
        if(!file1)
        {
          std::cout<<"Error opening output file"<<std::endl;
          continue;
        }
        std::string line;
        std::string token;
        int count = 0;
        while (std::getline(file1, line))
        {
          count++;
          std::map<File*, std::list<int> > *file_line =
          std::istringstream ss(line);
            while(std::getline(ss, token, ' ')) {
              if(token.empty())
                continue;
              pool[token][it].push_back(count);
            }
        }
      }
    }
    std::map<File*, std::list<int> > find_pattern(std::string& word){
      return pool[word];
    }
};

最佳答案

好消息:

为了让编译器在有问题的行上消失:

pool[token][&*it].push_back(count);

itstd::vector<File>::iterator , 和 pool是一个

std::map<std::string, std::map<File*, std::list<int> > >

所以,要得到一个普通的 File *对于迭代器,“&*”是典型的方法。

坏消息:

这是行不通的。一旦std::vector<File>重新分配后,指向其内容的所有 native 指针和迭代器都会失效。你的std::map将留下指向永不落地的指针。

如果这个结构所属的物体被复制或移动,所有东西也会从高轨道上被摧毁。

您需要彻底重新考虑数据和容器的整体设计。

关于c++ - 什么是插入列表 map 的正确方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41008946/

相关文章:

c++ - 使用 vector Android NDK - Eclipse CDT

c++ - 将 STL 映射转换为结构体

c++ - 在 C++ 中使用 LZMA SDK

c++ - 根中的空TH2F直方图

c++ - 英特尔 MIC 卸载——它如何与 STL 配合使用?

C++ STL - 为什么使用 !(w < *i) 而不是 (w==*i)

c++ - 后缀表达式求值

c++ - 为什么我的运算符重载不能正常工作?

c++ - 如何更新迭代(for 循环)求解器中的粒子位置

c++ - 模板参数依赖 [[nodiscard]]