初始化无序地图失败

时间:2016-09-22 23:01:57

标签: c++ c++11 dictionary unordered-map clang++

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

我正在编译

  

clang ++ -std = c ++ 11 -Wall -Wextra

尝试地图时:

#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
}

输出读取:

  

错误:二进制表达式的无效操作数('const class1'和   'const class1'){return __x&lt; __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 /比特/ hashtable_policy.h:830:23:   错误:未定义模板的隐式实例化   '的std ::哈希'              bool __use_ebo =!__ is_final(_Tp)&amp;&amp; __is_empty(_TP)GT;                                ^

     

/usr/lib/gcc/x86_64-pc-linux-gnu/4.8.4/include/g ++ - v4 / bits / hashtable_policy.h:1073:15:注意:在默认参数的实例化中   '_Hashtable_ebo_helper&lt; 1,std :: hash&gt;'需要在这里         private _Hashtable_ebo_helper&lt; 1,_H1&gt;,                 ^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~

     

/usr/lib/gcc/x86_64-pc-linux-gnu/4.8.4/include/g ++ - v4 / bits / hashtable_policy.h:1403:12:注意:在模板类的实例化中   'std :: __ detail :: _ Hash_code_base&gt;,std :: __ detail :: _ Select1st,std :: hash,std :: __ detail :: _ Mod_range_hashing,   std :: __ detail :: _ Default_ranged_hash,true&gt;'请在这里:公众   _Hash_code_base&lt; _Key,_ Value,_ExtractKey,_H1,_H2,_Hash,              ^

     

/usr/lib/gcc/x86_64-pc-linux-gnu/4.8.4/include/g ++ - V4 /比特/ hashtable.h:175:14:   注意:在模板类的实例化中   'std :: __ detail :: _ Hashtable_base&gt;,std :: __ detail :: _ Select1st,std :: equal_to,std :: hash,   的std :: __细节:: _ Mod_range_hashing,   的std :: __细节:: _ Default_ranged_hash,         std :: __ detail :: _ Hashtable_traits&gt;'这里要求       :public __detail :: _ Hashtable_base&lt; _Key,_Value,_ExtractKey,_Equal,                ^

     

/usr/lib/gcc/x86_64-pc-linux-gnu/4.8.4/include/g ++ - V4 /比特/ unordered_map.h:100:18:   注意:在模板类'std :: _ Hashtable&gt;的实例化中,         std :: allocator&gt; &gt;,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&gt;'这里要求         _Hashtable _M_h;                    ^

     

main.cpp:34:44:注意:在模板类的实例化中   “的std :: unordered_map,   std :: hash,std :: equal_to,   std :: allocator&gt; &GT; &GT;”这里请求std :: unordered_map fullMap;                                              ^

     

/usr/lib/gcc/x86_64-pc-linux-gnu/4.8.4/include/g ++ - V4 /比特/ 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 个答案:

答案 0 :(得分:2)

问题是std::map<key_type, value_type>需要为operator<正确定义key_type,在这种情况下,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; 一起使用,这需要以下框架:

java.time.MonthDay

答案 1 :(得分:1)

我认为这里的问题是您要打破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的内部工作要求类型是可清除的。那是你得到的第二个错误。

要解决此问题,请

  1. operator <定义自定义class1或比较器类型,然后使用std::map
  2. std::hash定义自定义class1,然后使用std::unordered_map

答案 2 :(得分:0)

在我们了解功能要求之前,很难建议最佳数据结构。但是下面的代码在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;

}

}