为什么这个 C++ STL分配器分配?
我正在尝试编写一个派生自 std::allocator
的自定义 STL 分配器,但不知何故,所有对 allocate()
的调用都转到基类。 我已将其范围缩小到以下代码:
template <typename T> class a : public std::allocator<T> {
public:
T* allocate(size_t n, const void* hint = 0) const {
cout << "yo!";
return 0;
}
};
int main()
{
vector<int, a<int>> v(1000, 42);
return 0;
}
我期望“哟!” 打印出来,然后出现一些可怕的错误,因为我实际上没有分配任何东西。 相反,程序运行良好并且不打印任何内容。 我究竟做错了什么?
我在 gcc 和 VS2008 中得到相同的结果。
I'm trying to write a custom STL allocator that is derived from std::allocator
, but somehow all calls to allocate()
go to the base class. I have narrowed it down to this code:
template <typename T> class a : public std::allocator<T> {
public:
T* allocate(size_t n, const void* hint = 0) const {
cout << "yo!";
return 0;
}
};
int main()
{
vector<int, a<int>> v(1000, 42);
return 0;
}
I expect "Yo!" to get printed, followed by some horrible error because I don't actually allocate anything. Instead, the program runs fine and prints nothing. What am I doing wrong?
I get the same results in gcc and VS2008.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
您将需要提供重新绑定成员模板以及 C++ 标准分配器要求中列出的其他内容。 例如,您需要一个模板复制构造函数,它不仅接受
allocator
,还接受allocator
。 例如,一段代码可能会这样做,例如 std::list 可能会这样做。如果不存在正确的重新绑定模板,或者不存在相应的复制构造函数,则代码将失败。 猜测需求是什么是没有用的。 迟早,您将不得不处理依赖于这些分配器要求的一部分的代码,并且该代码将会失败,因为您的分配器违反了这些要求。 我建议您在
20.1.5
中的标准副本中查看一些工作草案。You will need to provide a rebind member template and the other stuff that is listed in the allocator requirements in the C++ Standard. For example, you need a template copy constructor which accepts not only
allocator<T>
but alsoallocator<U>
. For example, one code might do, which a std::list for example is likely to doThe code will fail if there either exist no correct rebind template, or there exist no corresponding copy constructor. You will get nowhere useful with guessing what the requirements are. Sooner or later you will have to do with code that relies on one part of those allocator requirements, and the code will fail because your allocator violates them. I recommend you take a look at them in some working draft your your copy of the Standard in
20.1.5
.在这种情况下,问题是我没有重写分配器的重新绑定成员。 这个版本可以工作(在 VS2008 中):
我通过 STL 头调试发现了这一点。
这是否有效将完全取决于 STL 实现,所以我认为最终 Klaim 是对的,不应该这样做。
In this case, the problem is that I didn't override the rebind member of the allocator. This version works (in VS2008):
I found this by debugging through the STL headers.
Whether this works or not will be completely dependent on the STL implementation though, so I think that ultimately, Klaim is right in that this shouldn't be done this way.
我有两个用于创建自定义分配器的模板; 如果第一个用于自定义类型,则它会自动工作:
个用于当我们想要为带有标准分配器的预定义类型(例如 char、wchar_t、std::string 等)拥有自己的分配器时:
第二 上面的模板,对于您自己定义的类型,不需要任何进一步的处理,而是由标准容器类自动使用。 当用于标准类型时,第二个模板需要进一步的工作。 例如,对于 std::string,在声明该类型的变量时必须使用以下构造(最简单的是使用 typedef):
I have two templates for creating customized allocators; the first works automagically if it is used on a custom type:
The second is used when we want to have our own allocator for a predefined type with a standard allocator, for instance char, wchar_t, std::string, etc.:
The first template above, for your own defined type, does not require any further handling but is used automatically by the standard container classes. The second template requires further work when used on a standard type. For std::string, for example, one have to use the following construct when declaring variables of that type (it is simplest with a typedef):
以下代码按预期打印“yo” - 您看到的是我们的老朋友“未定义的行为”。
编辑:我刚刚查看了有关默认分配器的 C++ 标准。 没有禁止继承它。 事实上,据我所知,标准的任何部分都没有这样的禁止。
The following code prints "yo" as expected - what you were seeing was our old friend "undefined behaviour".
Edit: I just checked out the C++ Standard regarding the default allocator. There is no prohibition on inheriting from it. In fact, as far as I'm aware, there is no such prohibition in any part of the Standard.