Skip to main content
added 291 characters in body
Source Link
Snowhawk
  • 6.3k
  • 1
  • 18
  • 33
template<typename Key, typename U, std::size_t capacity>
class fixed_size_unordered_map {

The underlying map allows for policy customizations of the allocator, key comparator, and hash. You may want to provide these customization points to users.


    using iterator = typename std::unordered_map<Key, U>::iterator;
    using size_type = typename std::unordered_map<Key, U>::size_type;
    using value_type = typename std::unordered_map<Key, U>::value_type;

Are these common type definitions intended to be private?


    fixed_size_unordered_map(const fixed_size_unordered_map&) = default;
    fixed_size_unordered_map& operator=(const fixed_size_unordered_map&) = default;
    fixed_size_unordered_map(fixed_size_unordered_map&&) = default;
    fixed_size_unordered_map& operator=(fixed_size_unordered_map&&) = default;

If you explicitly define any of the special member functions for a class, you must define them all. The following five are considered special member functions. (see Rule of Zero/Three/Five)

  • Destructor
  • Copy Constructor
  • Copy Assignment
  • Move Constructor
  • Move Assignment

Either explicitly provide the missing destructor (Rule of Five) or don't explicitly define any of them (Rule of Zero).


    if(iter_queue[queue_idx] != items.end()){
        items.erase(iter_queue[queue_idx]);
    }
    const auto ret = items.insert(v);
    if(ret.second){

Undefined behavior here. If the iter_queue is full, you erase no matter what happens. If insert succeeds, an iterator get written backoverwrites the current invalid iterator in the LRU. If insertion doesn't succeed, you now have an invalidatednothing happens to the LRU and the current iterator is just invalid. Since

Check before erasing. Erase when inserting. Determine how you only want the LRU to erasebehave on inserts, you will needfailure to check before erasinginsert.


Consider using a circular buffer or writing your own LRU cache adaptor for some buffer type. By decoupling the LRU functionality, this object can focus on just adapting its interface to the composed-from objects. It also removes the need to explicitly define a default constructor (unless you define a conversion ctor).

template<typename Key, typename U, std::size_t capacity>
class fixed_size_unordered_map {

The underlying map allows for policy customizations of the allocator, key comparator, and hash. You may want to provide these customization points to users.


    using iterator = typename std::unordered_map<Key, U>::iterator;
    using size_type = typename std::unordered_map<Key, U>::size_type;
    using value_type = typename std::unordered_map<Key, U>::value_type;

Are these common type definitions intended to be private?


    fixed_size_unordered_map(const fixed_size_unordered_map&) = default;
    fixed_size_unordered_map& operator=(const fixed_size_unordered_map&) = default;
    fixed_size_unordered_map(fixed_size_unordered_map&&) = default;
    fixed_size_unordered_map& operator=(fixed_size_unordered_map&&) = default;

If you explicitly define any of the special member functions for a class, you must define them all. The following five are considered special member functions. (see Rule of Zero/Three/Five)

  • Destructor
  • Copy Constructor
  • Copy Assignment
  • Move Constructor
  • Move Assignment

Either explicitly provide the missing destructor (Rule of Five) or don't explicitly define any of them (Rule of Zero).


    if(iter_queue[queue_idx] != items.end()){
        items.erase(iter_queue[queue_idx]);
    }
    const auto ret = items.insert(v);
    if(ret.second){

Undefined behavior here. If the iter_queue is full, you erase. If insert succeeds, an iterator get written back. If insertion doesn't succeed, you now have an invalidated iterator. Since you only want to erase on inserts, you will need to check before erasing.


Consider using a circular buffer or writing your own LRU cache adaptor for some buffer type. By decoupling the LRU functionality, this object can focus on just adapting its interface to the composed-from objects. It also removes the need to explicitly define a default constructor (unless you define a conversion ctor).

template<typename Key, typename U, std::size_t capacity>
class fixed_size_unordered_map {

The underlying map allows for policy customizations of the allocator, key comparator, and hash. You may want to provide these customization points to users.


    using iterator = typename std::unordered_map<Key, U>::iterator;
    using size_type = typename std::unordered_map<Key, U>::size_type;
    using value_type = typename std::unordered_map<Key, U>::value_type;

Are these common type definitions intended to be private?


    fixed_size_unordered_map(const fixed_size_unordered_map&) = default;
    fixed_size_unordered_map& operator=(const fixed_size_unordered_map&) = default;
    fixed_size_unordered_map(fixed_size_unordered_map&&) = default;
    fixed_size_unordered_map& operator=(fixed_size_unordered_map&&) = default;

If you explicitly define any of the special member functions for a class, you must define them all. The following five are considered special member functions. (see Rule of Zero/Three/Five)

  • Destructor
  • Copy Constructor
  • Copy Assignment
  • Move Constructor
  • Move Assignment

Either explicitly provide the missing destructor (Rule of Five) or don't explicitly define any of them (Rule of Zero).


    if(iter_queue[queue_idx] != items.end()){
        items.erase(iter_queue[queue_idx]);
    }
    const auto ret = items.insert(v);
    if(ret.second){

Undefined behavior here. If the iter_queue is full, you erase no matter what happens. If insert succeeds, an iterator overwrites the current invalid iterator in the LRU. If insertion doesn't succeed, nothing happens to the LRU and the current iterator is just invalid.

Check before erasing. Erase when inserting. Determine how you want the LRU to behave on failure to insert.


Consider using a circular buffer or writing your own LRU cache adaptor for some buffer type. By decoupling the LRU functionality, this object can focus on just adapting its interface to the composed-from objects. It also removes the need to explicitly define a default constructor (unless you define a conversion ctor).

added 291 characters in body
Source Link
Snowhawk
  • 6.3k
  • 1
  • 18
  • 33
template<typename Key, typename U, std::size_t capacity>
class fixed_size_unordered_map {

The underlying map allows for policy customizations of the allocator, key comparator, and hash. You may want to provide these customization points to users.


    using iterator = typename std::unordered_map<Key, U>::iterator;
    using size_type = typename std::unordered_map<Key, U>::size_type;
    using value_type = typename std::unordered_map<Key, U>::value_type;

Are these common type definitions intended to be private?


    fixed_size_unordered_map(const fixed_size_unordered_map&) = default;
    fixed_size_unordered_map& operator=(const fixed_size_unordered_map&) = default;
    fixed_size_unordered_map(fixed_size_unordered_map&&) = default;
    fixed_size_unordered_map& operator=(fixed_size_unordered_map&&) = default;

Rule of Zero/Three/Five. IfIf you explicitly define any of the special member functions for a class, you must define them all. The following five are considered special member functions. (see Rule of Zero/Three/Five)

  • Destructor
  • Copy Constructor
  • Copy Assignment
  • Move Constructor
  • Move Assignment

Either explicitly provide the missing destructor (Rule of Five) or don't explicitly define any of them (Rule of Zero).


    if(iter_queue[queue_idx] != items.end()){
        items.erase(iter_queue[queue_idx]);
    }
    const auto ret = items.insert(v);
    if(ret.second){

Undefined behavior here. If the iter_queue is full, you erase. If insert succeeds, an iterator get written back. If insertion doesn't succeed, you now have an invalidated iterator. Since you only want to erase on inserts, you will need to check before erasing.


Consider using a circular buffer or writing your own LRU cache adaptor for some buffer type. By decoupling the LRU functionality, this object can focus on just adapting its interface to the composed-from objects. It also removes the need to explicitly define a default constructor (unless you define a conversion ctor).

template<typename Key, typename U, std::size_t capacity>
class fixed_size_unordered_map {

The underlying map allows for policy customizations of the allocator, key comparator, and hash. You may want to provide these customization points to users.


fixed_size_unordered_map(const fixed_size_unordered_map&) = default;
fixed_size_unordered_map& operator=(const fixed_size_unordered_map&) = default;
fixed_size_unordered_map(fixed_size_unordered_map&&) = default;
fixed_size_unordered_map& operator=(fixed_size_unordered_map&&) = default;

Rule of Zero/Three/Five. If you explicitly define any of the special member functions for a class, you must define them all. The following five are considered special member functions.

  • Destructor
  • Copy Constructor
  • Copy Assignment
  • Move Constructor
  • Move Assignment

Either explicitly provide the missing destructor (Rule of Five) or don't explicitly define any of them (Rule of Zero).


    if(iter_queue[queue_idx] != items.end()){
        items.erase(iter_queue[queue_idx]);
    }
    const auto ret = items.insert(v);
    if(ret.second){

Undefined behavior here. If the iter_queue is full, you erase. If insert succeeds, an iterator get written back. If insertion doesn't succeed, you now have an invalidated iterator. Since you only want to erase on inserts, you will need to check before erasing.


Consider using a circular buffer or writing your own LRU cache adaptor for some buffer type. By decoupling the LRU functionality, this object can focus on just adapting its interface to the composed-from objects. It also removes the need to explicitly define a default constructor (unless you define a conversion ctor).

template<typename Key, typename U, std::size_t capacity>
class fixed_size_unordered_map {

The underlying map allows for policy customizations of the allocator, key comparator, and hash. You may want to provide these customization points to users.


    using iterator = typename std::unordered_map<Key, U>::iterator;
    using size_type = typename std::unordered_map<Key, U>::size_type;
    using value_type = typename std::unordered_map<Key, U>::value_type;

Are these common type definitions intended to be private?


    fixed_size_unordered_map(const fixed_size_unordered_map&) = default;
    fixed_size_unordered_map& operator=(const fixed_size_unordered_map&) = default;
    fixed_size_unordered_map(fixed_size_unordered_map&&) = default;
    fixed_size_unordered_map& operator=(fixed_size_unordered_map&&) = default;

If you explicitly define any of the special member functions for a class, you must define them all. The following five are considered special member functions. (see Rule of Zero/Three/Five)

  • Destructor
  • Copy Constructor
  • Copy Assignment
  • Move Constructor
  • Move Assignment

Either explicitly provide the missing destructor (Rule of Five) or don't explicitly define any of them (Rule of Zero).


    if(iter_queue[queue_idx] != items.end()){
        items.erase(iter_queue[queue_idx]);
    }
    const auto ret = items.insert(v);
    if(ret.second){

Undefined behavior here. If the iter_queue is full, you erase. If insert succeeds, an iterator get written back. If insertion doesn't succeed, you now have an invalidated iterator. Since you only want to erase on inserts, you will need to check before erasing.


Consider using a circular buffer or writing your own LRU cache adaptor for some buffer type. By decoupling the LRU functionality, this object can focus on just adapting its interface to the composed-from objects. It also removes the need to explicitly define a default constructor (unless you define a conversion ctor).

Source Link
Snowhawk
  • 6.3k
  • 1
  • 18
  • 33

template<typename Key, typename U, std::size_t capacity>
class fixed_size_unordered_map {

The underlying map allows for policy customizations of the allocator, key comparator, and hash. You may want to provide these customization points to users.


fixed_size_unordered_map(const fixed_size_unordered_map&) = default;
fixed_size_unordered_map& operator=(const fixed_size_unordered_map&) = default;
fixed_size_unordered_map(fixed_size_unordered_map&&) = default;
fixed_size_unordered_map& operator=(fixed_size_unordered_map&&) = default;

Rule of Zero/Three/Five. If you explicitly define any of the special member functions for a class, you must define them all. The following five are considered special member functions.

  • Destructor
  • Copy Constructor
  • Copy Assignment
  • Move Constructor
  • Move Assignment

Either explicitly provide the missing destructor (Rule of Five) or don't explicitly define any of them (Rule of Zero).


    if(iter_queue[queue_idx] != items.end()){
        items.erase(iter_queue[queue_idx]);
    }
    const auto ret = items.insert(v);
    if(ret.second){

Undefined behavior here. If the iter_queue is full, you erase. If insert succeeds, an iterator get written back. If insertion doesn't succeed, you now have an invalidated iterator. Since you only want to erase on inserts, you will need to check before erasing.


Consider using a circular buffer or writing your own LRU cache adaptor for some buffer type. By decoupling the LRU functionality, this object can focus on just adapting its interface to the composed-from objects. It also removes the need to explicitly define a default constructor (unless you define a conversion ctor).