Hill
10/17/2008 12:00:00 PM
On 10?17?, ??4?26?, Kai-Uwe Bux <jkherci...@gmx.net> wrote:
> Hill wrote:
> > On 10?17?, ??2?08?, Kai-Uwe Bux <jkherci...@gmx.net> wrote:
> >> Hill wrote:
> >> > I want a class Table which saves one list of Pair<int,std::string>.
> >> > And I want that it has following behaviour:
>
> >> > Table t;//now t is empty
> >> > try{
> >> > int i = t["me"];// I want this call to an empty table will throw a
> >> > exception [case 1]
> >> > }
> >> > catch(...){
> >> > std::cout << "It's a empty table,bad operator" << std::endl;
> >> > t["me"] = 0;//and i hope this call can work well [case 2]
> >> > }
>
> >> First, a clarification about the specs: what about
>
> >> int i = t["here"];
>
> >> where t is not empty but no entry for "here" is to be found?
>
> >> > Could some one tell me how to define this class Table?
> >> > How to define operator for case 1 and case 2?
>
> >> > class Table
> >> > {
> >> > public:
> >> > class Bad_op{};
> >> > struct Pair
> >> > {
> >> > int data;
> >> > std::string str;
> >> > };
> >> > Table(const Table& table);
> >> > Table();
> >> > ~Table();
> >> > Table& operator= (const Table& table);
> >> > //int& operator[](const std::string& str);???????
> >> > //nst int& operator[](const std::string& str)const;???????
> >> > private:
> >> > std::vector<Pair> m_Vec;
> >> > };
>
> >> Why a vector of pairs? It seems that all you need is a thin wrapper
> >> around std::map< std::string, int >.
>
> >> Best
>
> >> Kai-Uwe Bux- ??????? -
>
> >> - ??????? -
>
> > Yes , When i say "empty" , i mean the table has a emplty list.
> > It's just a exercise. Not realistic class.
>
> In that case, you could try something like this:
>
> #include <map>
> #include <stdexcept>
> #include <string>
> #include <iostream>
>
> template < typename Key, typename Mapped >
> class table : public std::map< Key, Mapped > {
>
> struct proxy {
>
> table * the_table;
> Key the_key;
>
> proxy ( table * ptr, Key const & key )
> : the_table ( ptr )
> , the_key ( key )
> {}
>
> proxy & operator= ( Mapped const & rhs ) {
> static_cast< std::map< Key, Mapped > * >
> ( the_table )->operator[]( the_key ) = rhs;
> return ( *this );
> }
>
> operator Mapped & ( void ) const {
> if ( the_table->empty() ) {
> throw ( std::exception() );
> }
> return ( static_cast< std::map< Key, Mapped > * >
> ( the_table )->operator[]( the_key ) );
> }
>
> };
>
> struct const_proxy {
>
> table * the_table;
> Key the_key;
>
> const_proxy ( table * ptr, Key const & key )
> : the_table ( ptr )
> , the_key ( key )
> {}
>
> operator Mapped const & ( void ) const {
> if ( the_table->empty() ) {
> throw ( std::exception() );
> }
> return ( static_cast< std::map< Key, Mapped > * >
> ( the_table )->operator[]( the_key ) );
> }
>
> };
>
> public:
>
> table ( void ) :
> std::map< Key, Mapped > ()
> {}
>
> template < typename A >
> table ( A a ) :
> std::map< Key, Mapped > ( a )
> {}
>
> template < typename A, typename B >
> table ( A a, B b ) :
> std::map< Key, Mapped > ( a, b )
> {}
>
> proxy operator[] ( Key const & key ) {
> return ( proxy( this, key ) );
> }
>
> const_proxy operator[] ( Key const & key ) const {
> return ( proxy( this, key ) );
> }
>
> };
>
> int main ( void ) {
> table< std::string, int > t;
> {
> try{
> int i = t[ "me" ];
> }
> catch(...){
> std::cout << "It's a empty table,bad operator" << std::endl;
> }
> }
> {
> t[ "me" ] = 0;
> }
> {
> try{
> int i = t[ "me" ];
> }
> catch(...){
> std::cout << "It's a empty table,bad operator" << std::endl;
> }
> }
>
> }
>
> Best
>
> Kai-Uwe Bux- ??????? -
>
> - ??????? -
By overloading operator= and operator Mapped& , We distinguish the
lvalue and rvalue.
It's a good idear. Thanks.