简体   繁体   中英

C++ STL algorithms to add element in list

I want to know if anyone has a quick way for adding an element to a std::list<T*> if the element is not already in it.

It's a generic function and I can not use loops so something like this

template <class T>
bool Class<T>::addElement(const T* element)
{
    for (list<T*>::iterator it = list_.begin(); it != list_.end(); it++)
    {
        if (element == *it)
            return false;
    }
    list_.push_back(element);
    return true;
}

Is not ok because of the loop. Does anyone have ideas?

Why is what you have "not ok"? Looks perfectly fine and readable to me (modulo missing typename ).

If you really don't want to use a loop, you can accomplish the same by using the algorithm to does precisely that loop: std::find :

template <class T>
bool Class<T>::addElement(const T* element)
{
    if (std::find(list_.begin(), list_.end(), element) != list_.end()) {
        return false;
    }

    list_.push_back(element);
    return true;
}

If you can add other members to your class, you could add an index such as a std::unordered_set . That container stores a list of unique values, and can be searched for specific values in O(1) complexity, which implies that no full-loop search is done by the implementation for checking if the value already exists. It will stay fast even if you have a lot of values already stored.

With std::list, using library functions such as std::find will avoid explicitely writing a loop, but the implementation will perform the loop and this will be slow when a lot of values are already stored (O(n) complexity)

You can use intrusive list instead of the std::list. In this case each element in the list keeps its node data, so you can just query that data to find out if the element is already in the list. The disadvantage is that all elements in this list must be able to provide such data, and you can't put in such lists, for example, integer or boolean elements.

If you still need the std::list and/or the elements can be of any type, then the only way of fast queryng whether the element already exists in the list is to use an index. The indexes can be stored in separate std::unordered_set for fast lookups. You can use for indexes either the list's values "as is" or calculate the indexes using any custom function.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM