Я хочу хранить ограниченное количество элементов в контейнере. Я не хочу использовать массив, потому что я хочу избежать ненужных вызовов конструктора объекта. Я не хочу использовать std::vector
из-за неявного malloc
вызов (я хочу минимизировать доступ к куче для максимальной согласованности кэша).
Поэтому я решил определить свой собственный контейнер, что-то вроде этого:
template<typename T, size_t capacity> class my_array {
private:
char buffer[sizeof(T)*capacity];
...
public:
T& operator[](size_t i) { return *(T*)&buffer[i*sizeof(A)]; }
...
};
Но когда я пытаюсь использовать этот контейнер, я получаю предупреждения компилятора о нарушении правил строгого алиасинга. Я прочитал о строгом псевдониме и понимаю, почему оптимизация компилятора может привести к сбою кода выше.
Как мне обойти это?
Что странно, что у моего компилятора нет претензий к моему кастому object_pool
класс, который, среди прочего, я использую для пользовательского распределителя для своих ассоциативных структур данных STL. Этот класс выглядит очень похоже на вышеупомянутый (использует char[]
и делает подобный актерский состав). Я не могу понять, в чем разница между ними.
использование std::array
, , , , , , , , , , , , , !
Если вы не собираетесь использовать std:array
затем
char buffer[sizeof(T)*capacity];
должно быть
T buffer[capacity]
Вот почему поддержка шаблонов typename
в первую очередь.
использование std::aligned_storage
если вы не хотите инициализировать объекты как std::array
требует. Вы, вероятно, столкнетесь с проблемой выравнивания, так как ваша структура может быть назначена нечетному адресу.
Псевдоним с char
массив для использования в качестве хранилища должен быть в порядке, я не уверен, о чем ваш компилятор. Это действительно минимальный тест?
Я выяснил загадочное решение, сравнивая точно с object_pool
класс, на который я ссылался в моем первоначальном посте.
Я заменил
T& operator[](size_t i) { return *(T*)&buffer[i*sizeof(A)]; }
с
T* operator[](size_t i) {
if (...) {
return (T*)&buffer[i*sizeof(A)];
}
return NULL;
}
где ...
любой предикат, который я знаю, всегда будет оценивать true
, но который компилятор не достаточно умен, чтобы понять, всегда будет оценивать true
,
Мне было бы любопытно, если кто-нибудь может объяснить точно, что происходит здесь через голову компилятора. Я использую gcc 4.4.3.