Connecting Tech Pros Worldwide Help | Site Map

STL MAP, how to restrict

  #1  
Old November 15th, 2006, 04:35 PM
Haro Panosyan
Guest
 
Posts: n/a
#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)
  #2  
Old November 15th, 2006, 04:45 PM
Victor Bazarov
Guest
 
Posts: n/a

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


  #3  
Old November 15th, 2006, 04:55 PM
Noah Roberts
Guest
 
Posts: n/a

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.

  #4  
Old November 15th, 2006, 05:05 PM
mlimber
Guest
 
Posts: n/a

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

  #5  
Old November 15th, 2006, 05:45 PM
Haro Panosyan
Guest
 
Posts: n/a

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.
  #6  
Old November 15th, 2006, 06:05 PM
mlimber
Guest
 
Posts: n/a

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

Closed Thread


Similar Threads
Thread Thread Starter Forum Replies Last Post
Why not add namespace feature into standard C? toolmaster@163.com answers 32 February 9th, 2006 12:35 PM
Restricting base class visibility Rennie deGraaf answers 12 January 11th, 2006 05:15 PM
Is C99 the final C? Michael B. answers 193 November 14th, 2005 04:46 PM
Alternatives to the C++ Standard Library? Steven T. Hatton answers 43 July 23rd, 2005 06:52 AM