如何抑制类型的自动初始化和破坏?尽管T buffer[100]
自动初始化buffer
的所有元素并在它们超出范围时将其销毁是一件很了不起的事情,但这不是我想要的行为。
#include <iostream>
static int created = 0,
destroyed = 0;
struct S
{
S()
{
++created;
}
~S()
{
++destroyed;
}
};
template <typename T, size_t KCount>
class fixed_vector
{
private:
T m_buffer[KCount];
public:
fixed_vector()
{
// some way to suppress the automatic initialization of m_buffer
}
~fixed_vector()
{
// some way to suppress the automatic destruction of m_buffer
}
};
int main()
{
{
fixed_vector<S, 100> arr;
}
std::cout << "Created:\t" << created << std::endl;
std::cout << "Destroyed:\t" << destroyed << std::endl;
return 0;
}
该程序的输出为:
Created: 100
Destroyed: 100
我希望它是:
Created: 0
Destroyed: 0
我唯一的想法是使
m_buffer
成为某种琐碎构造和破坏的类型,例如char
,然后依靠operator[]
为我包装指针数学,尽管这似乎是一个骇人听闻的解决方案。另一种解决方案是使用malloc
和free
,但这提供了我不希望的间接级别。我之所以想这样做,是因为我在制造一个容器,并且不想为我不使用的东西支付初始化开销。例如,如果我的
main
函数是:int main()
{
{
std::vector<S> vec;
vec.reserve(50);
}
std::cout << "Created:\t" << created << std::endl;
std::cout << "Destroyed:\t" << destroyed << std::endl;
return 0;
}
输出将是正确的:
Created: 0
Destroyed: 0
最佳答案
您可以将数组创建为char
的数组,然后在需要时使用placement new
创建元素。
template <typename T, size_t KCount>
class Array
{
private:
char m_buffer[KCount*sizeof(T)]; // TODO make sure it's aligned correctly
T operator[](int i) {
return reinterpret_cast<T&>(m_buffer[i*sizeof(T)]);
}
重新阅读您的问题后,您似乎想要一个稀疏数组,有时有时将其称为map; o)(当然,性能特征是不同的...)
template <typename T, size_t KCount>
class SparseArray {
std::map<size_t, T> m_map;
public:
T& operator[](size_t i) {
if (i > KCount)
throw "out of bounds";
return m_map[i];
}