STL MAP, how to restrict 
November 15th, 2006, 04:35 PM
| | | |
#include <iostream>
#include <map>
#include <string>
using namespace std;
void InitMap( map<string, int>& Map)
{
Map["aa"] = 0;
Map["bb"] = 0;
}
int main() {
map<string, intMyMap;
InitMap( MyMap);
MyMap["aa"] = 10;// Questione 1
MyMap["cc"] = 20;// Question 2
map<string, int>::const_iterator iter;
for (iter=MyMap.begin(); iter != MyMap.end(); iter++) {
cout << iter->first << " " << iter->second << endl;
}
return 0;
}
Question 1:
How do I create my own map, which would allow me to check during
MyMap["aa"] = 10;
that values for "aa" can be from 0 to 5, so the above assignment
would print error message.
Question 2:
How do I prevent my map to be only 2 elements, "aa" and "bb", so
creation of new element "cc" would not be allowed.
Thanks,
-haro
(I tried and failed, I googled and failed, so I came here.
Please excuse if this is very simple or discribed somewhere) | 
November 15th, 2006, 04:45 PM
| | | | re: STL MAP, how to restrict
Haro Panosyan wrote: Quote:
#include <iostream>
#include <map>
#include <string>
>
using namespace std;
>
>
void InitMap( map<string, int>& Map)
{
Map["aa"] = 0;
Map["bb"] = 0;
}
>
int main() {
>
map<string, intMyMap;
>
InitMap( MyMap);
>
MyMap["aa"] = 10;// Questione 1
>
MyMap["cc"] = 20;// Question 2
>
map<string, int>::const_iterator iter;
for (iter=MyMap.begin(); iter != MyMap.end(); iter++) {
cout << iter->first << " " << iter->second << endl;
}
>
return 0;
>
}
>
>
Question 1:
>
How do I create my own map, which would allow me to check during
>
MyMap["aa"] = 10;
>
that values for "aa" can be from 0 to 5, so the above assignment
would print error message.
>
>
Question 2:
>
How do I prevent my map to be only 2 elements, "aa" and "bb", so
creation of new element "cc" would not be allowed.
>
Thanks,
-haro
(I tried and failed, I googled and failed, so I came here.
Please excuse if this is very simple or discribed somewhere)
| What you seem to need is a "wrapper" for 'std::map'. Since your
own 'map' is not an extension of 'std::map' (you want to impose
limitations on 'std::map' contents, which means your map is not
a std::map in the pure OO sense, see LSP), you should consider
private inheritance and re-implementation of the interface with
pre- and post-conditions verified in your implementations.
V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask | 
November 15th, 2006, 04:55 PM
| | | | re: STL MAP, how to restrict
Haro Panosyan wrote: Quote:
>
How do I create my own map, which would allow me to check during
>
MyMap["aa"] = 10;
>
that values for "aa" can be from 0 to 5, so the above assignment
would print error message.
>
>
Question 2:
>
How do I prevent my map to be only 2 elements, "aa" and "bb", so
creation of new element "cc" would not be allowed.
| It sounds to me like a map is totally inappropriate for your needs.
You should consider a different container or even no container at all.
You're using none of map's features. | 
November 15th, 2006, 05:05 PM
| | | | re: STL MAP, how to restrict
Haro Panosyan wrote: Quote:
#include <iostream>
#include <map>
#include <string>
>
using namespace std;
>
>
void InitMap( map<string, int>& Map)
{
Map["aa"] = 0;
Map["bb"] = 0;
}
>
int main() {
>
map<string, intMyMap;
>
InitMap( MyMap);
>
MyMap["aa"] = 10;// Questione 1
>
MyMap["cc"] = 20;// Question 2
>
map<string, int>::const_iterator iter;
for (iter=MyMap.begin(); iter != MyMap.end(); iter++) {
cout << iter->first << " " << iter->second << endl;
}
>
return 0;
>
}
>
>
Question 1:
>
How do I create my own map, which would allow me to check during
>
MyMap["aa"] = 10;
>
that values for "aa" can be from 0 to 5, so the above assignment
would print error message.
| Create a class that does range checking and automatically converts to
and from int, e.g. (untested code):
#include <map>
#include <string>
#include <exception>
template<typename T, T lower, T upper>
class RangeCheckedVal
{
T val_;
static T Validate( const T& val )
{
if( val < lower || val upper )
{
throw std::range_error( "Value out of range" );
}
return val;
}
public:
RangeCheckedVal( const T& val = lower )
: val_( Validate(val) )
{}
operator T() const { return val_; }
};
int main()
{
std::map<std::string, RangeCheckedVal<int,0,5 myMap;
myMap[ "aa" ] = 5; // ok
myMap[ "bb" ] = 10; // throws an exception
} Quote:
Question 2:
>
How do I prevent my map to be only 2 elements, "aa" and "bb", so
creation of new element "cc" would not be allowed.
| Make the map const. To do this, you'd need to initialize the class on
declaration somehow, e.g.:
template<class K, class V>
class MapInitializer
{
typedef std::map<K,VMap;
Map m_;
public:
operator Map() const { return m_; }
MapInitializer& Add( const K& k, const V& v )
{
m_[k] = v;
return *this;
}
};
const std::map<std::string,intmyMap
= MapInitializer<std::string, int>()
.Add( "aa", 9 )
.Add( "bb", 42 );
Of course, if the map is const, the [] operator won't work (outside the
initializer) since it inserts a key/value pair if one doesn't exist,
but std::map::find() is safer anyway.
Cheers! --M | 
November 15th, 2006, 05:45 PM
| | | | re: STL MAP, how to restrict
Please find my comments bellow inserted.
mlimber wrote: Quote:
Haro Panosyan wrote:
> Quote:
>>#include <iostream>
>>#include <map>
>>#include <string>
>>
>>using namespace std;
>>
>>
>>void InitMap( map<string, int>& Map)
>>{
>> Map["aa"] = 0;
>> Map["bb"] = 0;
>>}
>>
>>int main() {
>>
>> map<string, intMyMap;
>>
>> InitMap( MyMap);
>>
>> MyMap["aa"] = 10;// Questione 1
>>
>> MyMap["cc"] = 20;// Question 2
>>
>> map<string, int>::const_iterator iter;
>> for (iter=MyMap.begin(); iter != MyMap.end(); iter++) {
>> cout << iter->first << " " << iter->second << endl;
>> }
>>
>> return 0;
>>
>>}
>>
>>
>>Question 1:
>>
>>How do I create my own map, which would allow me to check during
>>
>>MyMap["aa"] = 10;
>>
>>that values for "aa" can be from 0 to 5, so the above assignment
>>would print error message.
| >
>
Create a class that does range checking and automatically converts to
and from int, e.g. (untested code):
>
#include <map>
#include <string>
#include <exception>
>
template<typename T, T lower, T upper>
class RangeCheckedVal
{
T val_;
>
static T Validate( const T& val )
{
if( val < lower || val upper )
{
throw std::range_error( "Value out of range" );
}
return val;
}
>
public:
RangeCheckedVal( const T& val = lower )
: val_( Validate(val) )
{}
>
operator T() const { return val_; }
};
>
int main()
{
std::map<std::string, RangeCheckedVal<int,0,5 myMap;
myMap[ "aa" ] = 5; // ok
myMap[ "bb" ] = 10; // throws an exception
}
>
>
| Thank,
This is nice, but I think this way both "aa" and "bb" would have
same range. What I wanted, is somehow to overwrite assignment, and
check if "aa" then range is 0 to 5, if "bb" then range is 3 to 9
for example. Quote: Quote:
>>Question 2:
>>
>>How do I prevent my map to be only 2 elements, "aa" and "bb", so
>>creation of new element "cc" would not be allowed.
| >
>
Make the map const. To do this, you'd need to initialize the class on
declaration somehow, e.g.:
>
template<class K, class V>
class MapInitializer
{
typedef std::map<K,VMap;
Map m_;
public:
operator Map() const { return m_; }
>
MapInitializer& Add( const K& k, const V& v )
{
m_[k] = v;
return *this;
}
};
>
const std::map<std::string,intmyMap
= MapInitializer<std::string, int>()
.Add( "aa", 9 )
.Add( "bb", 42 );
>
Of course, if the map is const, the [] operator won't work (outside the
initializer) since it inserts a key/value pair if one doesn't exist,
but std::map::find() is safer anyway.
>
Cheers! --M
>
| I will need more time to exercise this. | 
November 15th, 2006, 06:05 PM
| | | | re: STL MAP, how to restrict
Haro Panosyan wrote: Quote: Quote: Quote:
>Question 1:
>
>How do I create my own map, which would allow me to check during
>
>MyMap["aa"] = 10;
>
>that values for "aa" can be from 0 to 5, so the above assignment
>would print error message.
|
Create a class that does range checking and automatically converts to
and from int, e.g. (untested code):
#include <map>
#include <string>
#include <exception>
template<typename T, T lower, T upper>
class RangeCheckedVal
{
T val_;
static T Validate( const T& val )
{
if( val < lower || val upper )
{
throw std::range_error( "Value out of range" );
}
return val;
}
public:
RangeCheckedVal( const T& val = lower )
: val_( Validate(val) )
{}
operator T() const { return val_; }
};
int main()
{
std::map<std::string, RangeCheckedVal<int,0,5 myMap;
myMap[ "aa" ] = 5; // ok
myMap[ "bb" ] = 10; // throws an exception
} | >
Thank,
This is nice, but I think this way both "aa" and "bb" would have
same range. What I wanted, is somehow to overwrite assignment, and
check if "aa" then range is 0 to 5, if "bb" then range is 3 to 9
for example.
| Then you'll probably want to implement your own class that encapsulates
a map (or some other data structure).
Cheers! --M |  | | | | /bytes/about
We are a network of experts and professionals in IT and software development that help one another with answers to tough questions and share insights.
Get the best answers to your questions from over 225,689 network members.
|