写不下去了

turing-complete 2014-11-04 02:35:23
1、有功能类似的开源类吗?(我没有找到)
2、有自己实现过的童鞋,可以分享一下吗?


下面是我试图实现,但由于时间问题又放弃了的部分代码。
(一直有这个需求,但个人没有能力去写基础库,就一直用boost::unordered_map代替。)

#include <array>
#include <bitset>
#include <initializer_list>
#include <utility>

template <typename TEnum, typename TValue, int enumerators = TEnum::ENUMERATORS>
class EnumMap {
public:
EnumMap() = default;
~EnumMap() = default;
EnumMap(const EnumMap&) = delete;
EnumMap& operator=(const EnumMap&) = delete;
EnumMap(std::initializer_list<std::pair<TEnum, TValue>> init_list) {
for (const std::pair<TEnum, TValue>& p : init_list) {
array_[p.first] = p.second;
}
}

bool empty() const { return flags_.none(); }
size_t size() const { return flags_.count(); }
TValue& operator[](size_t i) { flags_.set(i); return array_[i]; }

private:
std::array<TValue, enumerators> array_;
std::bitset<enumerators> flags_;
};
...全文
348 12 打赏 收藏 转发到动态 举报
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
ri_aje 2014-11-05
  • 打赏
  • 举报
回复
引用 9 楼 mougaidong 的回复:
我不想写这段代码: namespace std { template <> struct hash <a_enum> { size_t operator () (a_enum const e) const { return e; } }; }
可以理解,为每个枚举类型提供类似的代码很无聊。unordered 容器不支持枚举类型是个标准库缺陷,c++14 修正了,明确要求支持。你要是不想用楼上那种替代方案,或者类似于这样的东西:

template <typename Key, typename Value>
using unordered_map = std::unordered_map < typename std::underlying_type<Key>::type, Value >;
那就只能升级编译器了。 很不幸,就我所知,让 std::hash 支持所有枚举类型需要对标准库本身动手术。如果你手头的标准库不支持,没有非侵入式的扩展能够简单易行的提供通用支持。
turing-complete 2014-11-05
  • 打赏
  • 举报
回复
多谢,我明白大致方向了。
引用 11 楼 ri_aje 的回复:
[quote=引用 9 楼 mougaidong 的回复:] 我不想写这段代码: namespace std { template <> struct hash <a_enum> { size_t operator () (a_enum const e) const { return e; } }; }
可以理解,为每个枚举类型提供类似的代码很无聊。unordered 容器不支持枚举类型是个标准库缺陷,c++14 修正了,明确要求支持。你要是不想用楼上那种替代方案,或者类似于这样的东西:

template <typename Key, typename Value>
using unordered_map = std::unordered_map < typename std::underlying_type<Key>::type, Value >;
那就只能升级编译器了。 很不幸,就我所知,让 std::hash 支持所有枚举类型需要对标准库本身动手术。如果你手头的标准库不支持,没有非侵入式的扩展能够简单易行的提供通用支持。[/quote]
FancyMouse 2014-11-04
  • 打赏
  • 举报
回复
那就写个template<typename T>struct myhash只做static_cast<size_t>(e),然后template<typename T1, typename T2> using EnumMap = std::unordered_map<T1, T2, myhash<T1>>。你既然愿意写EnumMap那就当myhash代替了EnumMap。像这样:

#include<iostream>
#include<string>
#include<unordered_map>
#include<functional>
enum class test_enum
{
	e1,
	e2,
	e3,
};
template<typename T>
struct myhash
{
	size_t operator () (T e)const {return static_cast<size_t>(e);}
};
template<typename T1, typename T2>
using EnumMap = std::unordered_map<T1, T2, myhash<T1>>;

int main()
{
	EnumMap<test_enum, std::string> m = {
		{test_enum::e1, "f1"},
		{test_enum::e2, "f2"},
		{test_enum::e3, "f3"},
	};
	for (const auto& p : m)
		std::cout<<static_cast<int>(p.first)<<": "<<p.second<<std::endl;
	return 0;
}
turing-complete 2014-11-04
  • 打赏
  • 举报
回复
我不想写这段代码: namespace std { template <> struct hash <a_enum> { size_t operator () (a_enum const e) const { return e; } }; }
引用 8 楼 ri_aje 的回复:
[quote=引用 7 楼 mougaidong 的回复:] 标准库的std::unordered_map不接受enum类型作为key。 如果能用也可以,就不用为了这个再include boost了。 [quote=引用 6 楼 ri_aje 的回复:] [quote=引用 5 楼 mougaidong 的回复:] 我想实现一个接口像map一样的容器,专门用来存放以枚举类型为key的std::pair结构。 最终目的是,不增加任何接口复杂性的前提下,要节省存储空间,提升操作(查询、遍历和插入等)效率。 但鉴于实现较为复杂,能支持基本功能就好了:size() , empty(), insert(), emplace(), find(),operator[](), begin() 和 end()。 [quote=引用 3 楼 ri_aje 的回复:] TEnum 和 TValue 的预期类型是什么?看 array 的用法,TEnum 必须能隐式转换成整形,看看这个是要求还是主楼实现的细节。 那个 bitset flags 的目的就仅仅是记录那些元素已经访问过了吗?
[/quote] 怎么看 std 的都能直接用,能说一下标准库的货为啥满足不了你的要求吗?浪费空间了,还是慢?[/quote][/quote] 有这事儿?试试这个。g++-4.8.2 和 clang++-3.5 都没问题。

#include <initializer_list>
#include <iostream>
#include <string>
#include <unordered_map>

enum a_enum
{
 test0,
 test1,
 test2,
 test3,
};

namespace std
{
 template <>
 struct hash <a_enum>
 {
  size_t operator () (a_enum const e) const
  {
   return e;
  }
 };
}

int main ()
{
 std::unordered_map<a_enum,std::string> const map
 {
  {test0,"test0"},
  {test1,"test1"},
  {test2,"test2"},
  {test3,"test3"},
 };

 for (auto const& pair : map)
 {
  std::cout << pair.first << " : " << pair.second << std::endl;
 }
}
[/quote]
ri_aje 2014-11-04
  • 打赏
  • 举报
回复
引用 7 楼 mougaidong 的回复:
标准库的std::unordered_map不接受enum类型作为key。 如果能用也可以,就不用为了这个再include boost了。 [quote=引用 6 楼 ri_aje 的回复:] [quote=引用 5 楼 mougaidong 的回复:] 我想实现一个接口像map一样的容器,专门用来存放以枚举类型为key的std::pair结构。 最终目的是,不增加任何接口复杂性的前提下,要节省存储空间,提升操作(查询、遍历和插入等)效率。 但鉴于实现较为复杂,能支持基本功能就好了:size() , empty(), insert(), emplace(), find(),operator[](), begin() 和 end()。 [quote=引用 3 楼 ri_aje 的回复:] TEnum 和 TValue 的预期类型是什么?看 array 的用法,TEnum 必须能隐式转换成整形,看看这个是要求还是主楼实现的细节。 那个 bitset flags 的目的就仅仅是记录那些元素已经访问过了吗?
[/quote] 怎么看 std 的都能直接用,能说一下标准库的货为啥满足不了你的要求吗?浪费空间了,还是慢?[/quote][/quote] 有这事儿?试试这个。g++-4.8.2 和 clang++-3.5 都没问题。

#include <initializer_list>
#include <iostream>
#include <string>
#include <unordered_map>

enum a_enum
{
 test0,
 test1,
 test2,
 test3,
};

namespace std
{
 template <>
 struct hash <a_enum>
 {
  size_t operator () (a_enum const e) const
  {
   return e;
  }
 };
}

int main ()
{
 std::unordered_map<a_enum,std::string> const map
 {
  {test0,"test0"},
  {test1,"test1"},
  {test2,"test2"},
  {test3,"test3"},
 };

 for (auto const& pair : map)
 {
  std::cout << pair.first << " : " << pair.second << std::endl;
 }
}
turing-complete 2014-11-04
  • 打赏
  • 举报
回复
标准库的std::unordered_map不接受enum类型作为key。 如果能用也可以,就不用为了这个再include boost了。
引用 6 楼 ri_aje 的回复:
[quote=引用 5 楼 mougaidong 的回复:] 我想实现一个接口像map一样的容器,专门用来存放以枚举类型为key的std::pair结构。 最终目的是,不增加任何接口复杂性的前提下,要节省存储空间,提升操作(查询、遍历和插入等)效率。 但鉴于实现较为复杂,能支持基本功能就好了:size() , empty(), insert(), emplace(), find(),operator[](), begin() 和 end()。 [quote=引用 3 楼 ri_aje 的回复:] TEnum 和 TValue 的预期类型是什么?看 array 的用法,TEnum 必须能隐式转换成整形,看看这个是要求还是主楼实现的细节。 那个 bitset flags 的目的就仅仅是记录那些元素已经访问过了吗?
[/quote] 怎么看 std 的都能直接用,能说一下标准库的货为啥满足不了你的要求吗?浪费空间了,还是慢?[/quote]
ri_aje 2014-11-04
  • 打赏
  • 举报
回复
引用 5 楼 mougaidong 的回复:
我想实现一个接口像map一样的容器,专门用来存放以枚举类型为key的std::pair结构。 最终目的是,不增加任何接口复杂性的前提下,要节省存储空间,提升操作(查询、遍历和插入等)效率。 但鉴于实现较为复杂,能支持基本功能就好了:size() , empty(), insert(), emplace(), find(),operator[](), begin() 和 end()。 [quote=引用 3 楼 ri_aje 的回复:] TEnum 和 TValue 的预期类型是什么?看 array 的用法,TEnum 必须能隐式转换成整形,看看这个是要求还是主楼实现的细节。 那个 bitset flags 的目的就仅仅是记录那些元素已经访问过了吗?
[/quote] 怎么看 std 的都能直接用,能说一下标准库的货为啥满足不了你的要求吗?浪费空间了,还是慢?
turing-complete 2014-11-04
  • 打赏
  • 举报
回复
我想实现一个接口像map一样的容器,专门用来存放以枚举类型为key的std::pair结构。 最终目的是,不增加任何接口复杂性的前提下,要节省存储空间,提升操作(查询、遍历和插入等)效率。 但鉴于实现较为复杂,能支持基本功能就好了:size() , empty(), insert(), emplace(), find(),operator[](), begin() 和 end()。
引用 3 楼 ri_aje 的回复:
TEnum 和 TValue 的预期类型是什么?看 array 的用法,TEnum 必须能隐式转换成整形,看看这个是要求还是主楼实现的细节。 那个 bitset flags 的目的就仅仅是记录那些元素已经访问过了吗?
mujiok2003 2014-11-04
  • 打赏
  • 举报
回复
要干啥?
ri_aje 2014-11-04
  • 打赏
  • 举报
回复
TEnum 和 TValue 的预期类型是什么?看 array 的用法,TEnum 必须能隐式转换成整形,看看这个是要求还是主楼实现的细节。 那个 bitset flags 的目的就仅仅是记录那些元素已经访问过了吗?
勤奋的小游侠 2014-11-04
  • 打赏
  • 举报
回复
是要实现什么功能?反正是没看懂你的代码,像是vector又像是map
zhousitiaoda 2014-11-04
  • 打赏
  • 举报
回复
看起来好高深的样子,学习下。

64,646

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧