在这段代码中,我得到一个不同的sizeof(T)如果分配器 是一个容器配置的一部分:为什么sizeof(T)在我的容器分配器内比在分配器中不同?
#include <iostream>
#include <set>
#include <cstddef>
class Item
{
int a;
unsigned char b, c, d;
int e, f, g;
public:
Item() { a = b = c = d = e = f = g = 0; }
bool operator<(const Item& item) const { return item.a < a; }
};
template <typename T> class TestAllocator
{
public:
typedef T value_type;
typedef size_t size_type;
typedef ptrdiff_t difference_type;
typedef T* pointer;
typedef const T* const_pointer;
typedef T& reference;
typedef const T& const_reference;
pointer address(reference x) const { return &x; }
const_pointer address(const_reference x) const { return &x; }
TestAllocator() { std::cout << "TestAllocator ctor: sizeof T:" << sizeof(T) << std::endl; }
template <typename U> TestAllocator(const TestAllocator<U>&) {}
~TestAllocator() {}
pointer allocate(size_type /*n*/, void * = 0) { return static_cast<T*>(new T()); }
void deallocate(pointer p, size_type /*n*/) { delete p; }
TestAllocator<T>& operator=(const TestAllocator&) { return *this; }
void construct(pointer p, const T& val) { new ((T*) p) T(val); }
void destroy(pointer p) { p->~T(); }
size_type max_size() const { return size_t(-1); }
template <typename U> struct rebind { typedef TestAllocator<U> other; };
template <typename U> TestAllocator& operator=(const TestAllocator<U>&) { return *this; }
};
typedef std::multiset<Item, std::less<Item>, TestAllocator<Item> > ItemMultiset;
int main(int /*argc*/, char** /*argv*/)
{
std::cout << "Instantiating allocator:" << std::endl;
TestAllocator<Item> ta;
std::cout << "Instantiating container:" << std::endl;
ItemMultiset ims;
return 0;
}
这里对我的gcc 7.2.1,我得到:
Instantiating allocator:
TestAllocator ctor: sizeof T:20
Instantiating container:
TestAllocator ctor: sizeof T:56
一些网上的编译器结果:
VC++在webcompiler.cloudapp.net说20和36
Coliru在coliru.stacked-crooked.co对于所有选定的gcc编译器,对于所有选定的gcc编译器,20和56,0235,164,106,1745,,20和56对于3.8, 或20和48对于3.8节C++ 11/14来说是如此。
为什么不同,为什么做一些结果填充每个结构成员?
我怎么能问什么比对“模式”的容器中,并 它应用到我的结构或代码,要不我怎么能告诉 容器使用我的代码的方式,以确保结果是 总是相同?
编辑:感谢下面的快速回复。
哇,很多空间使用。与其他容器进一步的结果:
Instantiating allocator:
TestAllocator ctor: sizeof T:20
Instantiating multiset:
TestAllocator ctor: sizeof T:56
Instantiating multimap:
TestAllocator ctor: sizeof T:20
Instantiating list:
TestAllocator ctor: sizeof T:40
Instantiating vector:
TestAllocator ctor: sizeof T:20
编辑2:
对于那些分配池工作的益处:
耶!我想我达到了我的目标。示例代码基于真实应用上的 ,正如您所期望的,分配器模板的 allocate
和deallocate
不只是调用new
和delete
。 他们交给一个游泳池。在周四之前,游泳池是全球性的 组块式多维(针对共同的预期大小请求的几个不同平面 )。 allocate
会通过 所需的字节数。然后我模板化了我们的 全局池,但有点笨拙的全局实例不得不 分别用所需的类型初始化 - 这就是发生故障的地方,这不是正确的类型!我看到为allocate
的机会只传递项目的数量而不是字节。 正如你所看到的,它没有按照我尝试的方式工作。我的错误是在模板化我们的池后不久,我没有意识到我可以在我的分配器模板类中删除它的一个静态实例。 繁荣,问题解决了,现在所有sizeof的都是一致的。池 现在工作正常,它现在是嵌入到 分配器模板类中的模板,它比我们的 先前版本更加精简和高效。用C++约25年,模板永远不会让我惊叹。谢谢你的帮助。
我想补充说这就是'rebind'成员模板的用途 - 容器使用它从'TestAllocator- '类型到它实际使用的'TestAllocator
类型。 –
aschepler