在這段代碼中,我得到一個不同的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