无序映射初始化失败
Failure on initialization of unordered map
并感谢您的任何意见。我有一个大型数据集,我正在尝试操作。我将活动元素保存在列表中,并在它们变为非活动状态时将其删除。我想在某些数据结构中保持所有元素处于活动状态和非活动状态。目前正在尝试使用地图或 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
}
输出读取:
error: invalid operands to binary expression ('const class1' and
'const class1') { return __x < __y; }
尽管我已经为 class1 重载了小于运算符。
此错误源于地图的重载括号运算符。
为了规避,我尝试存储在 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:
error: implicit instantiation of undefined template
'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: in instantiation of default argument for
'_Hashtable_ebo_helper<1, std::hash >' required here
private _Hashtable_ebo_helper<1, _H1>,
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/usr/lib/gcc/x86_64-pc-linux-gnu/4.8.4/include/g++-v4/bits/hashtable_policy.h:1403:12: note: in instantiation of template class
'std::__detail::_Hash_code_base >, std::__detail::_Select1st, std::hash, std::__detail::_Mod_range_hashing,
std::__detail::_Default_ranged_hash, true>' requested here : public
_Hash_code_base<_Key, _Value, _ExtractKey, _H1, _H2, _Hash,
^
/usr/lib/gcc/x86_64-pc-linux-gnu/4.8.4/include/g++-v4/bits/hashtable.h:175:14:
note: in instantiation of template class
'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 >' requested 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:
note: in instantiation of template class '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 >' requested here
_Hashtable _M_h;
^
main.cpp:34:44: note: in instantiation of template class
'std::unordered_map,
std::hash, std::equal_to,
std::allocator > > >' requested here std::unordered_map fullMap;
^
/usr/lib/gcc/x86_64-pc-linux-gnu/4.8.4/include/g++-v4/bits/functional_hash.h:58:12:
note: template is declared here
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 */
以下是我重载的 less than 运算符(我知道它不是最简洁或最有效的):
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;}
}
我认为这里的问题是您破坏了 std::map
和 std::unordered_map
接口所需的先决条件。
在 std::map
中,键类型需要能够使用小于运算符进行比较。这意味着您要么需要提供 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
。
在我们了解功能需求之前,很难建议最佳数据结构。但是下面的代码在 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;
}
}
问题是 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;
并感谢您的任何意见。我有一个大型数据集,我正在尝试操作。我将活动元素保存在列表中,并在它们变为非活动状态时将其删除。我想在某些数据结构中保持所有元素处于活动状态和非活动状态。目前正在尝试使用地图或 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
}
输出读取:
error: invalid operands to binary expression ('const class1' and 'const class1') { return __x < __y; }
尽管我已经为 class1 重载了小于运算符。 此错误源于地图的重载括号运算符。 为了规避,我尝试存储在 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: error: implicit instantiation of undefined template '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: in instantiation of default argument for '_Hashtable_ebo_helper<1, std::hash >' required here private _Hashtable_ebo_helper<1, _H1>, ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/usr/lib/gcc/x86_64-pc-linux-gnu/4.8.4/include/g++-v4/bits/hashtable_policy.h:1403:12: note: in instantiation of template class 'std::__detail::_Hash_code_base >, std::__detail::_Select1st, std::hash, std::__detail::_Mod_range_hashing, std::__detail::_Default_ranged_hash, true>' requested here : public _Hash_code_base<_Key, _Value, _ExtractKey, _H1, _H2, _Hash, ^
/usr/lib/gcc/x86_64-pc-linux-gnu/4.8.4/include/g++-v4/bits/hashtable.h:175:14: note: in instantiation of template class '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 >' requested 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: note: in instantiation of template class '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 >' requested here _Hashtable _M_h; ^
main.cpp:34:44: note: in instantiation of template class 'std::unordered_map, std::hash, std::equal_to, std::allocator > > >' requested here std::unordered_map fullMap; ^
/usr/lib/gcc/x86_64-pc-linux-gnu/4.8.4/include/g++-v4/bits/functional_hash.h:58:12: note: template is declared here 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 */
以下是我重载的 less than 运算符(我知道它不是最简洁或最有效的):
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;}
}
我认为这里的问题是您破坏了 std::map
和 std::unordered_map
接口所需的先决条件。
在 std::map
中,键类型需要能够使用小于运算符进行比较。这意味着您要么需要提供 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
。
在我们了解功能需求之前,很难建议最佳数据结构。但是下面的代码在 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;
}
}
问题是 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;