我正在使用IAR作为嵌入式项目的编译器。我正在尝试为列表等基本类型引入一些模板,但是创建的每个STL列表对象相对于我们当前的C样式实现增加了大约200个字节的代码大小。 我试图实现STL列表的一小部分,希望获得更小的代码占用空间,但最终比完整的STL列表更重。 我在使用模板时做了一些可怕的错误吗?
由于
P.S。请注意,代码未经测试,因此可能包含龙。
#ifndef __LINK_LIST_HPP__
#define __LINK_LIST_HPP__
#include <stdint.h>
#include <stdlib.h>
template <typename T> class list
{
private:
struct LinkListElement
{
T payload;
LinkListElement* next;
LinkListElement* prev;
};
public:
class iterator
{
// Need access to LinkListElement struct
friend class list;
public:
iterator() : m_cur_item(NULL){}
iterator(LinkListElement* elem) : m_cur_item(elem){}
iterator(const iterator& other) : m_cur_item(other.m_cur_item){}
~iterator(){}
iterator& operator=(const iterator& other)
{
m_cur_item = other.m_cur_item;
return *this;
}
bool operator==(const iterator& other) const
{
// Compare by position, ignoring the payload contents when comparing iterators.
return (m_cur_item->next == other.m_cur_item->next) &&
(m_cur_item->prev == other.m_cur_item->prev);
}
bool operator!=(const iterator& other) const
{
return !(*this == other);
}
// Prefix increment operator.
iterator& operator++()
{
increment();
return *this;
}
// Postfix increment operator.
iterator operator++(int)
{
iterator copy(*this);
increment();
return copy;
}
// Prefix decrement operator.
iterator& operator--()
{
decrement();
return *this;
}
// Postfix decrement operator.
iterator operator--(int)
{
iterator copy(*this);
decrement();
return copy;
}
T& operator*()
{
// Just so we won't crash, but behavior is undefined.
if (m_cur_item == NULL)
{
return dummy;
}
return m_cur_item->payload;
}
T* operator->()
{
if (m_cur_item == NULL)
{
return NULL;
}
return &(m_cur_item->payload);
}
private:
void increment()
{
if (m_cur_item == NULL || m_cur_item->next == NULL)
{
return;
}
m_cur_item = m_cur_item->next;
}
void decrement()
{
if (m_cur_item == NULL || m_cur_item->prev == NULL)
{
return;
}
m_cur_item = m_cur_item->prev;
}
LinkListElement* m_cur_item;
static T dummy;
};
// Need access to internal LinkListElement pointer
friend class iterator;
list()
{
// Add sentinel to mark end of list.
m_tail = new LinkListElement;
m_tail->next = m_tail;
m_tail->prev = m_tail;
m_head = m_tail;
}
~list()
{
// Clear entire list except for sentinel
clear();
// Destroy sentinel
delete m_tail;
m_head = NULL;
m_tail = NULL;
}
T& back()
{
// empty list with only sentinel. Result of back() is undefined
if (empty())
{
// TODO: Show some debug error
}
return m_tail->prev->payload;
}
T& front()
{
if (empty())
{
// TODO: Show some debug error
}
// m_head is always defined even if list is empty
return m_head->payload;
}
size_t size()
{
return m_count;
}
bool empty()
{
// head == tail means the list is empty
return m_head == m_tail;
}
iterator begin()
{
return iterator(m_head);
}
iterator end()
{
return iterator(m_tail);
}
iterator insert(iterator position, const T& payload)
{
// Validate position by finding it in our list
iterator find = begin();
while (find != end() && find != position)
{
++find;
}
if (find == end())
{
// TODO: Show some debug error
return position;
}
return insert_before(find.m_cur_item, payload);
}
void push_back(const T& payload)
{
insert_before(m_tail, payload);
}
void push_front(const T& payload)
{
insert_before(m_head, payload);
}
iterator erase(iterator position)
{
// Validate position by finding it in our list
iterator find = begin();
while (find != end() && find != position)
{
++find;
}
if (find == end())
{
// TODO: Show some debug error
return position;
}
return remove_at(find.m_cur_item);
}
//iterator erase(iterator first, iterator last); // Implement only if needed
void pop_back()
{
if (!empty())
{
// Don't remove the sentinel
remove_at(m_tail->prev);
}
}
void pop_front()
{
if (!empty())
{
remove_at(m_head);
}
}
void remove(const T& value)
{
iterator iter = begin();
while (iter != end())
{
iterator remove = iter++;
if (*remove == value)
{
remove_at(remove.m_cur_item);
}
}
}
void clear()
{
while (!empty())
{
pop_back();
}
}
private:
iterator insert_before(LinkListElement* existing, const T& payload)
{
// Allocate memory and save the element
LinkListElement* new_elem = new LinkListElement;
// For classes types (not pointer to object) this should invoke copy constructor
new_elem->payload = payload;
new_elem->prev = existing->prev;
new_elem->next = existing;
existing->prev = new_elem;
++m_count;
if (existing == m_head)
{
m_head = new_elem;
}
return iterator(new_elem);
}
iterator remove_at(LinkListElement* to_remove)
{
// Allocate memory and save the element
LinkListElement* prev = to_remove->prev;
LinkListElement* next = to_remove->next;
prev->next = next;
next->prev = prev;
--m_count;
if (to_remove == m_head)
{
m_head = next;
}
delete to_remove;
return iterator(prev);
}
LinkListElement* m_head;
LinkListElement* m_tail;
uint32_t m_count;
};
template <typename T> T list<T>::iterator::dummy;
#endif
答案 0 :(得分:3)
您的代码具有STL没有的各种功能和检查。所以你最终会得到更多代码是有意义的。
是的,STL具有您的代码所没有的许多功能。但是你没有使用它们中的任何一个,所以它们不会出现在你的代码中。 STL是使用模板设计的,因此您不会为不使用的内容付费。
你不太可能改善STL。如果您需要添加功能,请添加它们。你不需要重新发明轮子。