“地图”不是有效的模板

时间:2014-01-21 15:03:36

标签: c++ map duplicates

好的,我有一个上学的项目。它是显示目录中的所有共享文件。我有一个朋友帮我编写代码,这就是我们提出的:

void GroupIntoEquivClasses (string base_directory, map <string, vector <string>> &classes)
{   
    vector <string> files_and_dirs;
    GetFilesAndDirectoriesRecursive(base_directory, files_and_dirs);
    for (int i=0;i<files_and_dirs.size();i++)
    {
        if(IsFile(files_and_dirs[i]))
        {
            classes      [ReadFileContents(files_and_dirs[i])].push_back(files_and_dirs);
        }
    }
}

我使用了头文件filesystem.h,它是由老师和助手提供的:

#include "stdafx.h"
#include "filesystem.h"
#include <fstream>
#include <map>
#include <string>
#include <Windows.h>

using std::ifstream;

bool IsFile(const string& path) {
  DWORD attributes = GetFileAttributesA(path.c_str());
  return !(attributes & FILE_ATTRIBUTE_DIRECTORY);
}

bool IsDirectory(const string& path) {
  DWORD attributes = GetFileAttributesA(path.c_str());
  return attributes & FILE_ATTRIBUTE_DIRECTORY;
}

bool IsValid(const string& path) {
  DWORD attributes = GetFileAttributesA(path.c_str());
  return attributes != INVALID_FILE_ATTRIBUTES;
}

string StripBasePath(const string& path, const string& base_path) {
  if (base_path == path.substr(0, base_path.size())) {
    string new_path = path.substr(base_path.size());
    while (new_path.size() > 0 && (new_path[0] == '\\' || new_path[0] == '/')) {
      new_path.erase(new_path.begin());
    }
    return new_path;
  } else {
    return path;
  }
}

string StripLastPathComponent(const string& path) {
  string result = path;
  int n = result.size();
  // Remove trailing forward and backward slashes.
  while (n > 0 && (result[n - 1] == '/' || result[n - 1] == '\\')) {
    n--;
    result.erase(result.begin() + n);
  }
  // Remove everything until a forward or backward slash.
  while (n > 0 && result[n - 1] != '/' && result[n - 1] != '\\') {
    n--;
    result.erase(result.begin() + n);
  }
  return result;
}

string ReadFileContents(const string& filename) {
  ifstream stream(filename.c_str(), std::ifstream::binary);
  string content;
  char buf[BUFFER_SIZE];
  while (!stream.fail() && !stream.eof()) {
    stream.read(buf, BUFFER_SIZE);
    content += string(buf, stream.gcount());
  }
  stream.close();
  return content;
}

size_t FileSizeInBytes(const string& filename) {
  // TODO: implement more efficiently.
  return ReadFileContents(filename).size();
}

vector<string> GetFilesAndDirectoriesFlat(const string& directory) {
  vector<string> files_and_directories;

  string path = directory + "\\*";
  WIN32_FIND_DATAA find_data;
  HANDLE find_data_handle = FindFirstFileA(path.c_str(), &find_data);

  if (find_data_handle == INVALID_HANDLE_VALUE) {
    return files_and_directories;
  }

  while (true) {
    if (string(find_data.cFileName) != "." &&
        string(find_data.cFileName) != "..") {
      files_and_directories.push_back(find_data.cFileName);
    }
    if (!FindNextFileA(find_data_handle, &find_data)) break;
  }
  FindClose(find_data_handle);
  return files_and_directories;
}

void GetFilesAndDirectoriesRecursive(
    const string& base_path,
    vector<string>& files_and_directories) {

  files_and_directories.push_back(base_path);
  if (IsDirectory(base_path)) {
    vector<string> files_and_directories_flat =
        GetFilesAndDirectoriesFlat(base_path);
    for (int i = 0; i < files_and_directories_flat.size(); i++) {
      string name = files_and_directories_flat[i];
      GetFilesAndDirectoriesRecursive(
          base_path + "\\" + name,
          files_and_directories);
    }
  }
} 

如果缺少第#include <map>行,则在主文件中,void GroupIntoEquivClasses (string base_directory, map <string, vector <string>> &classes) map带有下划线且IntelliSense说:“不是有效模板”。如果#include <map>没有丢失,则在主文件中,在classes [ReadFileContents(files_and_dirs[i])].push_back(files_and_dirs); . push_back下划线。

我的问题是:如何删除或绕过该错误(因为我甚至无法编译我的项目)以及如何显示任何类型的结果?

1 个答案:

答案 0 :(得分:1)

此:

classes[ReadFileContents(files_and_dirs[i])].push_back(files_and_dirs);

应该是:

classes[ReadFileContents(files_and_dirs[i])] = files_and_dirs;

现在你正试图将矢量插入到矢量中。相反,你应该分配矢量。

为了完整起见,这里有两种不同的方式将内容插入std::map<K, V>

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

int main()
{
    std::vector<std::string> v = { "Foo", "Bar", "Blah" };

    // Version 1
    std::map<std::string, std::vector<std::string>> m;
    for(const std::string& s: v)
    {
        m[s] = v;
        //m[s].push_back(v); <-- Not correct
    }

    // Version 2
    std::map<std::string, std::vector<std::string>> m2;
    for(const std::string& s: v)
    {
        m2.insert(std::make_pair(s, v));
    }

    return 0;
}