Reputation: 23
I have a trouble with adding a new values to a set<Value_Class>
that is in my map<Key, set<Values_Class>>
. When I try to add a value like this:
Key key(get<0>(key_args), get<1>(key_args));
if (!(get<0>(key_args) < 1 && get<0>(key_args) > m_existing_keys_set.size()) && m_existing_keys_set.find(key) != m_existing_keys_set.end())
{
Value_Class value(get<0>(value_args), get<1>(value_args), get<2>(value_args));
set<Value_Class> _temp_set{ value };
m_map_with_elements.emplace(move(key), move(_temp_set));
}
There's only the first value I added in the map. The other values just don't insert, there's always only the first added value. Can You help me and tell how should I solve a problem? The whole code:
#pragma once
#include <iostream>
#include <string>
#include <tuple>
#include <utility>
#include <map>
#include <set>
using namespace std;
class Main_Class
{
private: //private section for classes and some helper functions
class Value_Class; struct Key;
set<Key> m_existing_keys_set
{
{1, "Key"}
}; // all the existing keys will be stored here
/*----------------------classes start space------------------*/
///
/// Value_Class
///
class Value_Class
{
public:
private:
string m_value_name;
fouble m_value_double_data;
bool m_is_available;
public:
Value_Class(string val_name, double val_double_data, bool is_avialable) : //Values_Class Constructor
m_value_name(move(val_name)),
m_value_double_data(val_double_data),
m_is_available(is_avialable) {};
~Value_Class() {};
friend ostream& operator<<(ostream& os, const Value_Class& dish) {// Overloading the output << operator
return os << dish.m_value_name << " >-=-=-=-< Price: " << dish.m_value_double_data;
}
bool operator<(const Value_Class& dish) const {// Overloading the < operator
return tie(m_value_name, m_value_double_data, m_is_available) < tie(dish.m_value_name, dish.m_value_double_data, dish.m_is_available);
}
};
///
/// KEY
///
struct Key
{
typedef int dish_number_category_t;
typedef string dish_name_category_t;
private:
dish_number_category_t m_key_number;
dish_name_category_t m_key_name;
public:
Key(dish_number_category_t num, dish_name_category_t str) : // Key constructor
m_key_number(num),
m_key_name(move(str)) {};
bool operator<(const Key& rhs) const {
return tie(m_key_number, m_key_name) < tie(rhs.m_key_number, rhs.m_key_name);
}
friend ostream& operator<<(ostream& os, const Key& k) {
return os << k.m_key_name;
}
bool operator==(const Key& _key) const
{
return tie(_key.m_key_number, _key.m_key_name) == tie(m_key_number, m_key_name);
}
};
/*----------------------classes end space------------------*/
template <class... Args1, class... Args2>
void add_helper(tuple<Args1...> key_args,
tuple<Args2...> value_args) // Helper method
{
Key key(get<0>(key_args), get<1>(key_args));
if (!(get<0>(key_args) < 1 && get<0>(key_args) > m_existing_keys_set.size()) && m_existing_keys_set.find(key) != m_existing_keys_set.end())
{
Value_Class value(get<0>(value_args), get<1>(value_args), get<2>(value_args));
set<Value_Class> _temp_set{ value };
m_map_with_elements.emplace(move(key), move(_temp_set));
}
}
public: static Main_Class* get_instance();
private: // private section for all singleton stuff
Main_Class() {};
Main_Class(const Main_Class&) = delete;
Main_Class operator=(const Main_Class&) = delete;
static Main_Class* _instance; // The only object og the Maim_Class
map<Key, set<Value_Class>> m_map_with_elements; // the map
public: // public section for all the public functions
template <class... Args>
void add_new_element_to_a_map(Args&&... args)
{
add_helper(forward<Args>(args)...);
}
void print_map() const
{
for (auto& itr : m_map_with_elements)
{
cout << "Key: " << itr.first << endl;
for (auto& itr2 : itr.second)
cout << itr2 << endl;
}
}
};
Main_Class* Main_Class::_instance = 0;
Main_Class* Main_Class::get_instance()
{
if (_instance == 0)
_instance = new Main_Class();
return _instance;
} //Singleton access function
Thanks in advance
Upvotes: 0
Views: 178
Reputation: 555
You've assumed that std::map::emplace()
will effectively take care of the key duplication while the documentation said that it's not guaranteed.
The element may be constructed even if there already is an element with the key in the container, in which case the newly constructed element will be destroyed immediately.
check out std::map::emplace()
You can use std::map::erase()
to erase the item if it exists, then you will get the expected behavior.
template <class... Args1, class... Args2>
void add_helper(tuple<Args1...> key_args,
tuple<Args2...> value_args) // Helper method
{
Key key(get<0>(key_args), get<1>(key_args));
if (!(get<0>(key_args) < 1 && get<0>(key_args) > m_existing_keys_set.size()) && m_existing_keys_set.find(key) != m_existing_keys_set.end())
{
Value_Class value(get<0>(value_args), get<1>(value_args), get<2>(value_args));
set<Value_Class> _temp_set{ value };
m_map_with_elements.erase(key);
m_map_with_elements.emplace(move(key), move(_temp_set));
}
}
You can also provide your own hand-crafted function to handle this.
Upvotes: 1