Почему бы просто не использовать вектор?
std::vector<TObject> m_Container;
size_t key = m_Container.size();
m_Container.push_back(some_object);
Конечно, это может быть совершенно бесполезно, если у вас есть другие характеристики использования. Но так как вы описываете только вставку и необходимость ключа (то есть извлечения), трудно дать какой-либо другой четкий ответ. Но из этих двух требований std :: vector <> должно работать просто отлично.
Если у вас есть некоторые другие характеристики использования, такие как: (элементы могут быть удалены), (мы вставляем элементы в большие блоки), (мы вставляем элементы нечасто) и т. Д., Это будут интересные факты, которые могут изменить рекомендации, которые дают люди.
Вы упоминаете, что хотите искать идентификаторы неиспользуемых элементов. Это говорит о том, что вы, возможно, удаляете элементы, но я не вижу каких-либо явных требований или использования при удалении элементов.
Глядя на ваш код выше:
size_t key = (m_Container.end()--)->first + 1;
Это не делает то, что вы думаете, что делает.
Это тоже эквивалентно:
size_t key = m_Container.end()->first + 1;
m_Container.end()--;
Оператор декремента post изменяет lvalue. Но результатом выражения является исходное значение. Таким образом, вы применяете оператор -> к значению, возвращаемому функцией end (). Это (вероятно) неопределенное поведение.
См. Стандарт:
Раздел: 5.2.6 Увеличение и уменьшение
Значением выражения postfix ++ является значение его операнда.
m_Container.end()-- // This sub-expresiion returns m_Container.end()
Альтернатива:
#include <vector>
template<typename T>
class X
{
public:
T const& operator[](std::size_t index) const {return const_cast<X&>(*this)[index];}
T& operator[](std::size_t index) {return data[index];}
void remove(std::size_t index) {unused.push_back(index);}
std::size_t insert(T const& value);
private:
std::vector<T> data;
std::vector<std::size_t> unused;
};
template<typename T>
std::size_t X<T>::insert(T const& value)
{
if (unused.empty())
{
data.push_back(value);
return data.size() - 1;
}
std::size_t result = unused.back();
unused.pop_back();
data[result] = value;
return result;
}