我想知道如何创建类似std::map<T1, T2>(T1allocator, T2allocator, T1deallocator, T2deallocator)
的内容,以便当任何人尝试从任何堆中将一个键&lt; - &gt;值对插入我的地图或修改某些数据时,将在原始地图创建者中创建堆,而不是其他堆,试图传递给自己的数据?
假设我们有一个DLL库(在Windows上),我们在动态上(在运行时)将它附加到我们的主应用程序。该库(作为主应用程序)是使用静态运行时编译的。所以可能会得到2个不同的STL和deffenetly 2个不同的堆 - 一个带有DLL的一个带App。
现在说我们希望我们的插件/ dll只能使用主应用堆中的内存。
让我们看一些简单的演示代码。
我们创建了一个主要应用程序已知的简单插件界面:
class plugin:
{
public:
virtual void pass_and_modify_data( boost::shared_ptr<std::map<std::string, std::string> > a) =0;
};
我们创建了pugin DLL:
#include "plug_in_interface.h"
class my_plugin: public plugin
{
public:
virtual void pass_and_modify_data( boost::shared_ptr<std::map<std::string, std::string> > a)
{
a->insert(std::pair<std::string, std::string>("hello", "World"));
(*a)["world"] = "hello";
}
};
现在我们要将地图从我们的应用程序传递到插件,但是将所有传递给我们地图的walue分配到主应用程序堆上。
如何做这样的事情 - 如何让std::map
将给定的键和值重新分配到主应用程序哈希中,而不需要插件代码开发人员注意? (这里注意我的意思是像使用客户解除分配器放入地图字符串或写任何特殊的非平凡代码)
查看我要创建的sehe's答案和演示:
如果我写了,我的主要看起来像:
#include <iostream>
#include <string>
#include <boost/shared_ptr.hpp>
#include <boost/flyweight.hpp>
#include "plug_in_interface.h"
using namespace boost;
using namespace boost::flyweights;
typedef flyweight<
std::string,
hashed_factory<
boost::hash<std::string>,
std::equal_to<key_value>,
std::allocator<boost::mpl::_1> // here we get errors like C2065: 'key_value' : undeclared identifier
>
> customString;
int main()
{
// boring part - load plugin... into something like boost::shared_ptr<plugin> my_plugin
//intresting part - create map in main heap and make all its values and keys be forced to be allocated or reallocated in main heap
std::cout << std::endl << "Map allocator mased memory management:" << std::endl;
std::cin.get();
{
boost::shared_ptr<std::map<std::string, std::string> > a (new std::map<customString, customString>());
my_plugin->pass_and_modify_data(a);
std::cout << "modified data: " << (*a)["hello"] << (*a)["world"] << std::endl;
}
std::cout << "removed data" << std::endl;
std::cin.get();
}
目前我无法编译这个东西,因为定义了customString类型。编译器显示了大量的编译器错误。如何使类型def更正确?
一般来说,对于stl :: allocators来说,我真的很绝对,我真正需要的是分配器是多少绑定到堆(类似于我们可以用shared_ptrs),这样的事情可能吗?
答案 0 :(得分:1)
如果您只想提供功能到map
进行分配,那么您就不走运了。控制STL容器内存管理的标准方法是allocators。
您不能对密钥和值使用单独的分配器,因为std::map
只接受一个分配器模板参数(std::map<Key, Value, Predicate, Allocator>
)。但是没有理由这样做 - 两者的单个分配器就足够了。
如果您只想要一个自定义分配器,那么它很简单。您可以使用标准格式之一(alloc
,pthread_alloc
,single_client_alloc
或malloc_alloc
),或阅读this tutorial以了解如何编写自己的标准格式。如果您可以提供有关您尝试解决的问题的更多信息,我可以提供更有帮助的答案。
答案 1 :(得分:1)
您可以使用Boost Flywheight或Boost Optional。
虽然不完全像标准容器,但它们允许工厂/分配策略,您可以使用它。当然,你最终会得到另一种间接的方式,这可能是,也可能不是你想要的。
参见,例如http://www.boost.org/doc/libs/1_48_0/libs/flyweight/doc/tutorial/configuration.html#factories
hashed_factory<[Hash[,Pred[,Allocator]]]>
....假设我们想为std :: string flyweight配置hashed_factory,并使用特殊的哈希谓词special_hash和自定义分配器custom_allocator;这将指定如下:
typedef flyweight< std::string, hashed_factory< special_hash<std::string>, std::equal_to<key_value>, custom_allocator<boost::mpl::_1> > > customString;
由于Flyweights本质上是 immutable ,因此它们可以更好地用于键:
std::map<customString, int> my_funky_map;
现在,使用默认的地图分配器来指定应该分配地图的元素(对)的位置。