首页 文章

初始化无序映射失败

提问于
浏览
0

并感谢任何输入 . 我有一个大型数据集,我试图操纵 . 我在列表中保存活动元素,并在它们变为非活动状态时将其删除 . 我想在一些数据结构中保持所有元素处于活动和非活动状态 . 目前正在尝试 Map 或unordered_map,但欢迎任何建议 .

我正在编译

clang -std = c 11 -Wall -Wextra

在尝试 Map 时:

#include <map>
std::map <class1, std::string> fullMap;
//and later...
for (std::list<class1>::iterator x = l.begin(); x != l.end(); x++)
{
    fullMap[(*x)] =  s
}

输出读数:

error:二进制表达式的无效操作数('const class1'和'const class1'){return __x <__y; }

即使我为class1重载了less运算符 . 此错误源自map的重载括号运算符 . 绕过我尝试存储在unordered_map中 .

#include <unordered_map>
std::unordered_map <class1, std::string> fullMap;

并且程序在fullMap初始化时失败,更加令人困惑:

/usr/lib/gcc/x86_64-pc-linux-gnu/4.8.4/include/g -v4 / bits / hashtable_policy.h:830:23:错误:隐式实例化未定义模板'std :: hash'bool use_ebo =! is_final(_Tp)&& __is_empty(_Tp)> ^ /usr/lib/gcc/x86_64-pc-linux-gnu/4.8.4/include/g -v4 / bits / hashtable_policy.h:1073:15:note :在'_Hashtable_ebo_helper <1,std :: hash>'的默认参数实例化中,私有_Hashtable_ebo_helper <1,_H1>,^ ~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~ / usr / lib / gcc / x86_64-pc-linux-nuu / 4.8.8 / include / g -v4 / bits / hashtable_policy.h:1403:12:注意:在模板类的实例化中std :: __ detail :: _ Hash_code_base>,std :: __ detail :: _ Select1st,std :: hash,std :: __ detail :: _ Mod_range_hashing,std :: __ detail :: _ Default_ranged_hash,true>'在这里请求:public _Hash_code_base <_Key,_Value ,_ExtractKey,_H1,_H2,_Hash,^ / usr / lib / gcc / x86_64-pc-linux_gnu / 4.8.8 / include / g -v4 / bits / hashtable.h:175:14:注意:在实例化中模板类'std :: __ detail :: _ Hashtable_base>,std :: __ detail :: _Select1st,std :: equal_to,std :: hash,std :: __ detail :: _ Mod_range_hashing,std :: __ detail :: _ Default_ranged_hash,std :: __ detail :: _ Hashtable_traits>'request here:public __detail :: _ Hashtable_base <Key, Value, _ExtractKey,_Equal,^ /usr/lib/gcc/x86_64-pc-linux-gnu/4.8.4/include/g -v4 / bits / unordered_map.h:100:18:注意:在模板类'std的实例化中: :_Hashtable>,std :: allocator >>,std :: __ detail :: _ Select1st,std :: equal_to,std :: hash,std :: __ detail :: _ Mod_range_hashing,std :: __ detail :: _ Default_ranged_hash,std :: __ detail: :_Prime_rehash_policy,std :: __ detail :: _ Hashtable_traits>'在这里请求_Hashtable _M_h; ^ main.cpp:34:44:注意:在实例化模板类'std :: unordered_map,std :: hash,std :: equal_to,std :: allocator >>>'这里请求std :: unordered_map fullMap; ^ /usr/lib/gcc/x86_64-pc-linux-gnu/4.8.4/include/g -v4 / bits / functional_hash.h:58:12:注意:模板在这里声明为struct hash;

我试图将代码仅缩减到相关的块,但如果需要更多信息,请告诉我 . 感谢阅读,任何帮助表示赞赏 .

//
//  class1.hpp
//  class
//
//  Created by Roach on 9/3/16.
//  Copyright © 2016 Roach. All rights reserved.
//

#ifndef class1_hpp
#define class1_hpp

#include <iostream>
#include <sstream>
#include <iomanip>
#include <ctime>


class class1
{
public:
  class1 ();
  class1 (const class1& t); // copy constructor
  ~class1 (); // destructor
  class1& operator = (const class1& t); // assignment operator
  bool operator == (const class1& t); // comparison operator
  void setSetting2 (std::string t);
  void setSetting1 (std::string p);
  void setSetting3 (double d);
  void setSetting4 (double d);
  std::tm getTime () const;
  std::string getSetting2 () const;
  double getSetting3 () const;
  double getSetting4 () const;
  std::string getSetting1 () const;
  void setSetting3End (double d);
  void setSetting4End (double d);
  double getSetting3End () const;
  double getSetting4End () const;
  double getSetting3flag () const;
  double getSetting4flag () const;
  double getSetting3final () const; // in pips
  double getSetting4final () const; // in pips
  void processList (class1::class1 t);
  void setNew ();
  //void dump (std::ostream& os) const;

private:
  std::string setting1;
  double setting4;
  double setting3;
  std::tm setting2;
  double setting4End_;
  double setting3End_;
  bool setting4Flag_;
  bool setting3Flag_;
  double setting4final_; // in pips
  double setting3final_; // in pips
};
// stream extraction operator
std::ostream& operator << (std::ostream& os, const class1& s);
std::istream& operator >> (std::istream& is, class1& t);

endif /* class1_hpp */

以下是我的重载小于运算符(我知道它不是最简洁或最有效的):

bool class1::operator< (const class1& t)
{
  if (this->time_.tm_year < t.time_.tm_year) {return true;}
  else if (this->time_.tm_year > t.time_.tm_year) {return false;}
  else if (this->time_.tm_mon < t.time_.tm_mon) {return true;}
  else if (this->time_.tm_mon > t.time_.tm_mon) {return false;}
  else if (this->time_.tm_mday < t.time_.tm_mday) {return true;}
  else if (this->time_.tm_mday > t.time_.tm_mday) {return false;}
  else if (this->time_.tm_hour < t.time_.tm_hour) {return true;}
  else if (this->time_.tm_hour > t.time_.tm_hour) {return false;}
  else if (this->time_.tm_min < t.time_.tm_min) {return true;}
  else if (this->time_.tm_min > t.time_.tm_min) {return false;}
  else if (this->time_.tm_sec < t.time_.tm_sec) {return true;}
  else {return false;}
}

3 回答

  • 1

    在我们了解功能要求之前,很难建议最佳数据结构 . 但是下面的代码在GCC 4.9.3上对我有用 . 请检查您的包含文件和语法 .

    #include <iostream>
    #include <string>
    #include <map>
    #include <unordered_map>
    #include <list>
    
    using namespace std;
    
    int main()
    {
    //LIST
    std::list<int> myList;
    myList.push_front(1);
    myList.push_front(2);
    myList.push_front(3);
    myList.push_front(4);    
    
    //STRING
    string s = "Test";
    
    //MAP    
    std::map <int, std::string> fullMap;   
    for (std::list<int>::iterator x = myList.begin(); x != myList.end(); x++)
    {               
        fullMap.insert(std::make_pair(*x,s));
    
    }
    
    //UNORDERED MAP    
    std::unordered_map <int, std::string> fullUnorderedMap;   
    for (std::list<int>::iterator y = myList.begin(); y != myList.end(); y++)
    {        
         fullUnorderedMap.insert(std::make_pair(*y,s));
    }
    
    //PRINTING    
    for(auto it = fullMap.begin(); it != fullMap.end(); ++it)
    {
    
        cout<<it->first<<"       "<<it->second<<endl;
    
    }
    
    for(auto it = fullUnorderedMap.begin(); it != fullUnorderedMap.end(); ++it)
    {
    
        cout<<it->first<<"       "<<it->second<<endl;
    
    }
    

    }

  • 2

    问题是 std::map<key_type, value_type> 需要为 key_type 正确定义 operator< ,在这种情况下, operator< 未指定 const ,因此它与 std::map 不兼容,因为此数据结构要求比较器不以任何方式更改密钥对象 . 因此,解决方案是将 class1::operator< 标记为 const .

    第二个错误指出没有应用散列函数对象与 std::unordered_map 一起使用,这将需要以下框架:

    auto class1_hasher = [](const class1& c) -> std::size_t { return {some hash based on c}; }
    std::unordered_map<class1, std::string, decltype(class1_hasher)> um;
    
  • 0

    我认为这里的问题是你打破了 std::mapstd::unordered_map 接口所需的先决条件 .

    std::map 中,密钥类型需要能够使用less-than运算符进行比较 . 这意味着您需要提供 operator < 的重载,或者在使用 std::map 类型时提供自定义比较器 . 由于您没有提供使用类型执行此操作的方法,因此 std::map 的内部实现无法表达表单

    somethingOfTypeClass1 < somethingElseOfTypeClass1
    

    编译,因此您的错误消息 .

    当您切换到 std::unordered_map 时,遇到了麻烦,因为为了将某些内容存储为 std::unordered_map 中的某个键,您需要在自定义类型上专门化 std::hash 模板,因为 unordered_map 的内部工作要求该类型是可清除的 . 这是你得到的第二个错误 .

    要解决此问题

    • class1 定义自定义 operator < 或比较器类型,然后使用 std::map ,或者

    • class1 定义自定义 std::hash ,然后使用 std::unordered_map .

相关问题