Setter and Getter method for map - c++

string var;
void setvar(string ivar)
{
var=ivar;
}
string getVar() const
{
return var;
}
as same way how can i write setter and getter method for a map like this
std::map varmap;

You can write a getter or setter for a field that's a std::map just as you would any other field - just have the getter return a std::map and have the setter accept a std::map.
Of course, if you have a field that's a std::map that you're trying to use getters and setters on, that might suggest that there's a better way to structure the program. Can you provide more details about what you're trying to do?
EDIT: The above answer is for a slightly different question than the one you asked. It seems like what you're interested in is
Given a class with a std::map as a data member, write a function to set a given key/value pair and a function to return the value associated with a given key.
The setter logic for this is not too hard - you just write a function that takes in the key and value and associates the key with the value. For example:
void put(const string& key, const string& value) {
varmap[key] = value;
}
Writing a getter is trickier because there's no guarantee that there's a value associated with a particular key. When this happens, you have multiple options.
You could return a sentinel value. For example, you might return an empty string if the given value isn't stored in the map anywhere. This makes the code for using the function easier to read, but risks using an invalid value in code.
You could throw an exception. This would be good if it represents a serious error for the given value not to exist. This has the drawback that if you look up a value, you always need to try/catch the logic to avoid propagation of errors.
You could associate a default value with the key, then hand that back. If you're writing a program that represents a music library, for example, you might hand back "(none)" or "(unknown)" if you tried to look up the artist for a song on which you have no data, for example.
No one of these approaches works best, and you'll need to think over which is most appropriate to your particular circumstance.

Entries in a std::map<Key, Value> must have a key and a value. The normal way of getting and setting them is:
my_map[a_key] = new_value; // set
do_something_with(my_map[a_key]); // get and use...
If you want to add new functions, they probably wouldn't look like what you're proposing because:
your set is only given one parameter despite needing a key and value (admittedly, you could adopt some convention like having the first ':' or '=' separate them), and
the get() function doesn't provide any key.
You could instead have something more like:
void set(const Key&, const Value&);
std::string get(const Key&) const;
But, even if you have write permissions to do so, you shouldn't add that directly in the map header file - all C++ programs compiled on that computer will share that file and won't expect it to be modified. Any small mistake could cause trouble, and if you ship your program to another computer you won't be able to compile it there without making a similar modification - if that computer uses a different C++ compiler the necessary details of that modification may be slightly different too.
So, you can either write your own (preferably templated) class that derives from (inherits) or contains (composition) a std::map, providing your functions in your custom class. An inheritance based solution is easier and more concise to write:
template <typename Key, typename Value>
struct My_Map : std::map<Key, Value>
{
My_Map(...); // have to provide any non-default constructors you want...
void set(const Key& key, const Value& value) { operator[](key) = value; }
// if you want entries for non-existent keys to be created with a default Value...
Value& get(const Key& key) { return operator[](key); }
--- OR ---
// if you want an exception thrown for non-existent keys...
Value& get(const Key& key) { return at(key); }
const Value& get(const Key& key) const { return at(key); }
};
This is slightly dangerous if you're planning to pass My_Maps around by pointer and accidentally end up with a "new My_Map" pointer that's later deleted as a std::map pointer, as in:
void f(std::map<int, string>* p) { /* use *p */ delete p; }
My_Map<int, string>* p = new My_Map<int, string>;
f(p);
Still, in most programs there's no real danger of accidentally disposing of a map like this, so go ahead and do it.
Further, and this is the kind of thinking that'll make me unpopular with the Standard-fearing purists around here - because My_Map hasn't added any data members or other bases, the std::map<> destructor probably does all the necessary tear-down even though it's technically Undefined Behaviour. I'm NOT encouraging you to ignore the issue (and would consider it unprofessional in a job requiring robustness), but you can at least rest a little easier. I'd be curious to hear from anyone with any compiler/settings where it demonstrably doesn't operate safely.
If you use composition, you'll have to write your own "forwarding" functions to let you use My_Map like a std::map, accessing iterators, find, erase, insert etc.. It's a pain.

Setter and getter for std::map is no different except that you need to pass the necessary parameters for the setter. Assume if I have a struct and has a member variable whose type is std::map, whose key is of type char and data is of type int. Method signatures would be of the format -
void setEncode( char* key, int* data, const int& size ); Because, std::map requires a key, data and sizes of these arrays being passed. With out knowing size, it is unknown as how far to insert the elements in to the container.
std::map<char, int> getEncode() const ; const key word signifies it a non-modifying member function. Because it's functionality is to just return a variable of type std::map.
Example -
struct myMap
{
std::map<char, int> encode;
void setEncode( char* key, int* data, const int& size );
std::map<char, int> getEncode() const ;
};
void myMap::setEncode( char *key, int* data, const int& size )
{
int i=0;
while( i < size )
{
encode.insert(std::pair<char, int>(key[i], data[i]));
++i ;
}
}
std::map<char, int> myMap::getEncode() const
{
return encode;
}
Results IdeOne. This should give you an idea, but should also follow the general rules what #templatetypedef, #tony suggested.

Do you want to set a key value pair in an existing map(probably that's what you want) or create a new map itself?
void setvar(string key, int value)
{
myMap[key] = value;
}
int getVar(string key) const
{
return myMap[key];
}
where int and string are interchangeable
For latter you'll probably have to interate over all map values for setting and getter should be just to return that map pointer.

Related

Modify key of std::map

Is there a way to modify the key of a std::map or ? This example shows how to do so with rebalancing the tree. But what if I provide some guarantees that the key won't need to be rebalanced?
#include <vector>
#include <iostream>
#include <map>
class Keymap
{
private:
int key; // this key will be used for the indexing
int total;
public:
Keymap(int key): key(key), total(0)
{}
bool operator<(const Keymap& rhs) const{
return key < rhs.key;
}
void inc()
{
total++;
}
};
std::map<Keymap, int> my_index;
int main (){
std::map<Keymap, int> my_index;
Keymap k(2);
my_index.insert(std::make_pair(k, 0));
auto it = my_index.begin();
it->first.inc(); // this won't rebalance the tree from my understanding
return 0;
}
The modification won't compile because of the constness of it->first
Is there any way to override this behavior?
You could make inc const and total mutable
class Keymap
{
private:
int key; // this key will be used for the indexing
mutable int total;
public:
Keymap(int key): key(key), total(0)
{}
bool operator<(const Keymap& rhs) const{
return key < rhs.key;
}
void inc() const
{
total++;
}
};
But you do need to ask yourself why you are doing this, mutable isn't used much.
You're right that no rebalancing is going to happen.
If you cannot change the design and introduce surrogate read-only keys, your best option is to use Boost.MultiIndex container (I am not aware of reasonable alternatives). It is designed specifically for this purpose and has consistent built-in support of updating the indexed object, including the transactional variant. Documentation and code examples are here.
Generally, patterns like storing business entities in a self-keyed sets, having mutable keys serving additional purpose (counters and whatnot), etc. tend to have impact on maintenability, performance, and scalability of the code.
You could wrap your keys into a class that allows modification of const objects. One such class would be std::unique_ptr:
using KeymapPtr = std::unique_ptr<Keymap>;
struct PtrComp
{
template<class T>
bool operator()(const std::unique_ptr<T>& lhs, const std::unique_ptr<T>& rhs) const
{
return *lhs < *rhs;
}
};
template<class V>
using PtrMap = std::map<KeymapPtr, V, PtrComp>;
int main (){
PtrMap<int> my_index;
KeymapPtr k = std::make_unique<Keymap>(2);
my_index.emplace(std::move(k), 0);
auto it = my_index.begin();
it->first->inc(); // this won't rebalance the tree from my understanding
return 0;
}
Demo
Note that we have to supply a custom comparator object since we (presumably) want to sort by the key values, not the pointer values.
To be clear, this is not what unique_ptr is meant for, and the const semantics of smart pointers (which follow those of regular pointers) are a bit backwards from this perspective (why can I get a non-const reference from a const object? A linter may complain about this kind of use...), but it does the trick here. The same would of course work with naked pointers (where a T* const can have the T value changed but not the pointer location, whereas a const T* can have its location changed but not the T), but this mimics the ownership/lifetime model of your original code.
Needless to say, this opens the door to breaking the map invariants (breaking the sortedness by keys) so think twice before using it. But unlike const_casting your key directly, it is free of UB.
std::map and the other standard associative containers do not provide a way to do this without removing and adding an element, likely causing tree rebalancing side effects. You can go around the map key constness in various ways (e.g. using mutable members), but then it's entirely up to you to make sure you don't actually break the key ordering.
If you need this sort of efficiency but a bit more safety, you might consider changing the container to a boost::multi_index_container instead.
A std::map<K,V> is similar to:
namespace BMI = boost::multi_index;
using map_value_type = std::pair<K, V>;
using map_type = BMI::multi_index_container<
map_value_type,
BMI::indexed_by<BMI::ordered_unique<
BMI::member<map_value_type, &map_value_type::first>
>>>;
except that in a multi_index_container, the entire element is always const. If you want to be able to directly modify the second members, a means for that is described on this boost page.
multi_index_container provides two members the standard associative containers do not, replace and modify. Both of these will check for whether the modified element is in the same sort order or not. If it is, no rebalancing is done.
auto it = my_index.begin();
auto pair = *it;
pair.first.inc();
my_index.replace(it, pair);
// OR
auto it = my_index.begin();
my_index.modify(it, [](auto& pair) { pair.first.inc(); });

Optimal way to write two methods that return a value and reference of the same item in C++

Suppose that I have a class that has two methods. One of them should find an object in a container and return it by value, and the other one should return it by reference. Naturally, I want the first method to be const (in the sense of this being const) and the second one not to be.
Is there a way to re-use the code between these two methods without introducing a third method that they both rely on? Below I've given a toy example of the problem, where one should imagine that the find step is actually considerably more complicated.
In "possible implementation 1" below, there is an error due to the fact that I am calling (non-const) get_ref from within (const) get_value. In "possible implementation 2," the reference is created from a temporary copy of the value, which of course is a major problem.
In the case that a const reference is desired, then of course there is no problem, but assume that I actually want an ordinary reference.
// Header:
#include <string>
#include <map>
using std::string;
using std::map;
class Test {
public:
map< string, string > stuff;
string & get_ref( const string key );
string get_value( const string key ) const;
};
// Possible implementation 1:
string Test::get_value( const string key ) const {
return get_ref( key );
}
string & Test::get_ref( const string key ) {
return stuff.find( key )->second;
}
// Possible implementation 2 (obviously wrong, but here for the sake of pointing that out):
string Test::get_value( const string key ) const {
return stuff.find( key )->second;
}
string & Test::get_ref( const string key ) {
return get_value( key );
}
To directly answer the question, the only way to avoid using a third/private method is to cast the const-ness of this away.
Using the "possible implementation 1", alter as follows:
string Test::get_value( const string key ) const {
return const_cast<Test*>(this)->get_ref( key );
}
Now, to look a bit broader at two other issues: firstly, you should alter get_ref() so it does something sensible if stuff.find( key ) returns end() (the one-past-the-end iterator). Options include throwing an exception or returning an empty string.
Secondly, a simple efficiency improvement is to note that the method parameters pass strings by value, which can be easily and safely changed to pass const string& key.

Unchecked read from a map in a const function

Suppose the following:
struct C {
... // lots of other stuff
int get(int key) const { return m.at(key); } // This will never throw
private:
std::unordered_map<int, int> m;
};
Due to how the application works, I know that get never throws. I want to make get as fast as possible. So, I would like to make the access unchecked, i.e. I would like to write something like return m[key]. Of course, I cannot write exactly that while keeping get const. However, I want to keep get const, since it is logically const.
Here is the only (ugly) solution I came up with:
struct C {
... // lots of other stuff
int get(int key) const { return const_cast<C *>(this)->m[key]; }
private:
std::unordered_map<int, int> m;
};
Is there a better way?
One approach would be to use std::unordered_map::find:
struct C {
... // lots of other stuff
int get(int key) const { return m.find(key)->second; }
private:
std::unordered_map<int, int> m;
};
I object to the very reasoning behind this question. The overhead (of map.at() vs map[]) associated with catching an error due to unknown key is presumably tiny compared to the cost of finding the key in the first place.
Yet, you willingly take the serious risk of a run-time error just for such a marginal efficiency advantage that you presumably have not even validated/measured. You may think that you know that key is always contained in the map, but perhaps future code changes (including bugs introduced by others) may change that?
If you really know, then you should use
map.find(key)->second;
which makes the bug explicit if the iterator returned is invalid (i.e. equal to map.end()). You may use assert in pre-production code, i.e.
auto it = map.find(key);
assert(it!=map.end());
return it->second;
which in production code (when assert is an empty macro) is removed.

Overloaded [] operator for hash table to a vector

I am working on a simple hash table in C++. I have methods to insert, delete, and search the hash table for the specified key. I know that the C++ map STL container can handle my situation, but I would kind of like to code my own as an educational exercise.
Basically I have a hash table that will take a single string and map it to a vector of other strings. This is easy to do in a method because calling a .Add() or .Delete() will behave as expected. I would however like to create an overloaded [] operator to the class that is able to do these operations on the vector.
For example, if I want to add an item to the vector I can write something like this:
hashTable[string1] = newString;
This will set the new string as a member of my vector. The same can be said for delete and search.
hashTable[string1] = "";
cout << hashTable[string1] << endl;
My major problem is that I do not know how to overload the [] operator to gain this functionality. I have this function coded up right now. It works on a basic 1 to 1 string match, but not on a string to vector match.
//Return a reference to a vector to update then reassign?
vector& HashClass::operator[](const string index)
{
assert(size >= 0 && size < maxSize);
Hash(key);
return hashTable[index];
}
I think I'm most stuck on the idea of having a vector return that later needs to be assigned. As the user, I would find this kludgy.
This question is closely related to another question: what behavior do
you want when you access a non-existant value other than in an
assignment? In other words, what do you want to happen when you write:
std::cout << hashTable[string] << std::endl;
and string is not present in the table?
There are two possible approaches: you can consider it an error, and
throw an exception, or abort, or something similar; or you can return
some sort of default, built with the default constructor, or provided by
the client earlier.
The standard map and unordered_map take the second approach, using the
default constructor to construct a new value. This allows a very simple
solution: if operator[] isn't present, you insert it, initializing it
with the default value. Then you return a reference to it;
hashTable[string] = newString; assigns through the reference to an
already existing value.
In many use cases, the first approach will be preferable (perhaps with a
contains function, so you can test up front whether the operator[]
will find something or not). To implement the first approach, you must
first implement specific functions for each type of access:
template <typename Key, typename Value>
class HashTable
{
public:
Value* get( Key const& key ) const;
void set( Key const& key, Value const& value );
};
(I generally make these public; there's no reason to forbid their use by
a client.)
Then, you define operator[] to return a proxy, as follows:
template <typename Key, typename Value>
class HashTable
{
public:
class Proxy
{
HashTable* myOwner;
Key myKey;
public:
Proxy( HashTable* owner, Key const& key )
: myOwner( owner )
, myKey( key )
{
}
operator Value const&() const
{
Value const* result = myOwner->get( myKey );
if ( result == NULL ) {
// Desired error behavior here...
}
return *result;
}
Proxy const& operator==( Value const& value ) const
{
myOwner->set( myKey, value );
return *this;
}
};
Value* get( Key const& key ) const;
void set( Key const& key, Value const& value );
Proxy operator[]( Key const& key )
{
return Proxy( this, key );
}
};
Thus, when you write:
hashTable[key] = newString;
, the proxy's operator= will call hashTable.put( key, newString );
in other contexts, however, it will call the implicit type conversion on
the proxy, which calls hashTable.get( key ).
In some cases, even if you desire to return a default value, it may be
preferable to use this solution: the get function is not required to
insert anything into the hash table, so the table doesn't fill up with
all of the misses, and you can overload the operator[] on const, so
you can use it on a const hash table as well. Also, it doesn't
require the value type to have a default constructor.
It does have one disadvantage with respect to the solution used in the
standard; since you can't overload operator., you can't make the proxy
behave like a reference, and things like:
hashTable[string].someFunction();
don't work. A work-around is to overload operator-> in the proxy, but
this leads to a somewhat unnatural syntax:
hashTable[string]->someFunction(); // But the hash table contains
// values, not pointers!!!
(Don't be mislead by the implicit conversion to a reference. An
implicit conversion will not be considered for a in an expression
a.b.)
In C++, [] access to associative containers is generally given the semantics of default-constructing an object of the mapped type, inserting it with the key, and returning a reference to the inserted mapped object.
So your operator[] would be implemented as:
string& HashClass::operator[](const string index)
{
assert(size >= 0 && size < maxSize);
Hash(key);
vector &v = hashTable[index];
if (index in v) {
...
} else {
v.push_back(string());
return v.back();
}
}

How to create map with keys/values inside class body once (not each time functions from class are called)

I would like to create C++ class which would allow to return value by given key from map, and key by given value. I would like also to keep my predefined map in class content. Methods for getting value or key would be static. How to predefine map statically to prevent creating map each time I call getValue(str) function?
class Mapping
{
static map<string, string> x;
Mapping::Mapping()
{
x["a"] = "one";
x["b"] = "two";
x["c"] = "three";
}
string getValue(string key)
{
return x[key];
}
string getKey(string value)
{
map<string, string>::const_iterator it;
for (it = x.begin(); it < x.end(); ++it)
if (it->second == value)
return it->first;
return "";
}
};
string other_func(string str)
{
return Mapping.getValue(str); // I don't want to do: new Mapping().getValue(str);
}
Function other_func is called often so I would prefer to use map which is created only once (not each time when other_func is called). Do I have to create instance of Mapping in main() and then use it in other_func (return instance.getValue(str)) or is it possible to define map in class body and use it by static functions?
Is this what you want?
#include <map>
#include <string>
class Mapping
{
private:
// Internally we use a map.
// But typedef the class so it is easy to refer too.
// Also if you change the type you only need to do it in one place.
typedef std::map<std::string, std::string> MyMap;
MyMap x; // The data store.
// The only copy of the map
// I dont see any way of modifying so declare it const (unless you want to modify it)
static const Mapping myMap;
// Make the constructor private.
// This class is going to hold the only copy.
Mapping()
{
x["a"] = "one";
x["b"] = "two";
x["c"] = "three";
}
public:
// Public interface.
// Returns a const reference to the value.
// The interface use static methods (means we dont need an instance)
// Internally we refer to the only instance.
static std::string const& getValue(std::string const& value)
{
// Use find rather than operator[].
// This way you dont go inserting garbage into your data store.
// Also it allows the data store to be const (as operator may modify the data store
// if the value is not found).
MyMap::const_iterator find = myMap.x.find(value);
if (find != myMap.x.end())
{
// If we find it return the value.
return find->second;
}
// What happens when we don;t find anything.
// Your original code created a garbage entry and returned that.
// Could throw an exception or return a temporary reference.
// Maybe -> throw int(1);
return "";
}
};
First of all, you might want to look up Boost::MultiIndex and/or Boost::bimap. Either will probably help a bit with your situation of wanting to use either one of the paired items to look up the other (bimap is more directly what you want, but if you might need to add a third, fourth, etc. key, then MultiIndex may work better). Alternatively, you might want to just use a pair of sorted vectors. For situations like this where the data remains constant after it's been filled in, these will typically allow faster searching and consume less memory.
From there, (even though you don't have to make it explicit) you can handle initialization of the map object itself a bit like a singleton -- put the data in the first time it's needed, and from then on just use it:
class Mapping {
static map<string, string> x;
static bool inited;
public:
Mapping() {
if (!inited) {
x["a"] = "one";
x["b"] = "two";
x["c"] = "three";
inited = true;
}
}
string getValue(string const &key) { return x[key]; }
};
// This initialization is redundant, but being explicit doesn't hurt.
bool Mapping::inited = false;
map<string, string> Mapping::x;
With this your some_func could look something like this:
string some_func(string const &input) {
return Mapping().getValue(input);
}
This still has a little overhead compared to pre-creating and using an object, but it should be a lot less than re-creating and re-initializing the map (or whatever) every time.
If you are looking up the value from the key a lot, you will find it easier and more efficient to maintain a second map in parallel with the first.
You don't need to create a static map especially if you ever want to create multiple Mapping objects. You can create the object in main() where you need it, and pass it around by reference, as in:
string other_func(Mapping &mymap, string str)
{
return mymap.getValue(str);
}
Of course this raises questions about efficiency, with lots of strings being copied, so you might want to just call getValue directly without the extra overhead of calling other_func.
Also, if you know anything about the Boost libraries, then you might want to read up on Boost.Bimap which is sort of what you are implementing here.
http://www.boost.org/doc/libs/1_42_0/libs/bimap/doc/html/index.html
Static is bad. Don't. Also, throw or return NULL pointer on not found, not return empty string. Other_func should be a member method on the object of Mapping, not a static method. This whole thing desperately needs to be an object.
template<typename Key, typename Value> class Mapping {
std::map<Key, Value> primmap;
std::map<Value, Key> secmap;
public:
template<typename Functor> Mapping(Functor f) {
f(primmap);
struct helper {
std::map<Value, Key>* secmapptr;
void operator()(std::pair<Key, Value>& ref) {
(*secmapptr)[ref.second] = ref.first;
}
};
helper helpme;
helpme.secmapptr = &secmap;
std::for_each(primmap.begin(), primmap.end(), helpme);
}
Key& GetKeyFromValue(const Value& v) {
std::map<Value,Key>::iterator key = secmap.find(v);
if (key == secmap.end())
throw std::runtime_error("Value not found!");
return key->second;
}
Value& GetValueFromKey(const Key& k) {
std::map<Key, Value>::iterator key = primmap.find(v);
if (key == primmap.end())
throw std::runtime_error("Key not found!");
return key->second;
}
// Add const appropriately.
};
This code uses a function object to initialize the map, reverses it for you, then provides accessing methods for the contents. As for why you would use such a thing as opposed to a raw pair of std::maps, I don't know.
Looking at some of the code you've written, I'm guessing that you originate from Java. Java has a lot of things that C++ users don't use (unless they don't know the language) like singletons, statics, and such.