@star 你这个注释挺好。
那个map是应该作为一个静态变量。
这里其实更好的做法是把它作为一个类的静态变量,gcc下是没问题的,不过在msvc下会有运行期错误,不得已才放到外面。
网站首页 文章专栏 一个更好的异构容器
@star 你这个注释挺好。
那个map是应该作为一个静态变量。
这里其实更好的做法是把它作为一个类的静态变量,gcc下是没问题的,不过在msvc下会有运行期错误,不得已才放到外面。
purecpp
一个很酷的modern c++开源社区
purecpp社区自2015年创办以来,以“Newer is Better”为理念,相信新技术可以改变世界,一直致力于现代C++研究、应用和技术创新,期望通过现代C++的技术创新来提高企业生产力和效率。
社区坚持只发表原创技术文章,已经累计发表了一千多篇原创C++技术文章;
组织了十几场的C++沙龙和C++大会,有力地促进了国内外C++开发者之间的技术交流;
开源了十几个现代C++项目,被近百家公司所使用,有力地推动了现代C++在企业中的应用。
期待更多的C++爱好者能参与到社区C++社区的建设中来,一起为现代C++开源项目添砖加瓦,一起完善C++基础设施和生态圈。
purecpp社区邮箱: purecpp@163.com
祁大的思路很好,但没有注释好废脑子,我来加些注释和个人理解,指祁大指正。
/*
该方法,利用了fold express 的方式,将所有的类型数据依次展开访问,提供给visit函数进行访问,其通过模板隐藏生成了多个容器(容器个数和类型数应该是相同的),
该方法并为这些容器提供了统一的访问接口。我个人认为,使用该方法,应该给 items 加上static 限定,将其限定在本编译单元中,防止不同编译单元访问混乱。
不知理解对不?
*/
template<class T>
std::unordered_map<const heterogeneous_container*, std::vector<T>> items;
struct heterogeneous_container
{
public:
template<class T>
void push_back(const T& _t)
{
items<T>[this].push_back(_t);
}
template<class T>
void visit(T&& visitor)
{
// typename std::decay_t<T>::types T的退化类型,即去除掉T类型的所有修饰得到的祼类型,再由调用其无参构造函数。
visit_impl(visitor, typename std::decay_t<T>::types{});
}
template<typename... Args, class F>
void visit1(F&& visitor)
{
/*
关于type_list 文中未给出定义,通过从后面的visit_impl函数定义来看,其定义可能是如此:
template<class ...Args>
struct type_list{};
即只是对模板多参数的封装
*/
visit_impl(visitor, type_list<Args...>{});
}
private:
/*
1. template<> using , 这个c++11 引进来的类型重命名的好东西,可以套模板。
* 2. std::declval<T>(), 构造T类型的无参默认实例
3. .operator()(std::declval<U&>()) 这说明类型T是一个接受U类型参数的函数对象,即此处隐含了T类型是std::is_object
4. decltype, 返回该函数对象所对应的函数类型
5. 但这个声明visit_function<T,U> 类型 好像后面没有用到
*/
template<class T, class U>
using visit_function = decltype(std::declval<T>().operator()(std::declval<U&>()));
// 这是该方法的核心,即利用fole expression的方式(c++17),将多个类型逐次直接展开
template<class T, template<class...> class TLIST, class... TYPES>
void visit_impl(T&& visitor, TLIST<TYPES...>)
{
(..., visit_impl_help<std::decay_t<T>, TYPES>(visitor));
}
// 从上面关于items的定义,可以看出items<U>[this]的类型是vector<U>
template<class T, class U>
void visit_impl_help(T& visitor)
{
for (auto&& element : items<U>[this])
{
visitor(element);
}
}
};