469,910 Members | 1,471 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 469,910 developers. It's quick & easy.

Overloading Subscript operator

What I am trying to achieve here is depicted in the small program
below.

// Wrapit.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <map>
#include <list>

using namespace std;

class A
{

private:
string a;
string b;
string c;
public:
A(){}

};

class B
{

private:
string a;
string b;
string c;

public:
B(){cout << "B constructor is being called \n";}
};
class C
{
private:
map<string, A * aobj;
map<string, B * bobj;
public:

C(){cout << "Constructor of C called \n";}

template <class T>
T& operator [] (string key)
{
cout << "Operator [] called \n";
return new A(); //if the key has a particular text in it return
new A
// otherwise return new B();
}

};

int _tmain(int argc, _TCHAR* argv[])
{
C c;
c["abcd"] = new A();
c["efgh"] = new B();

return 0;
}
Obviously the above program will give you compiler errors.

I am trying to put a wrapper around the maps. And the insertion to the
maps is done through an
(eg . c["abcd"] = new A()) overloaded [] operator. Further I want to
use just one [] version of the function, but inside I will determine
whether I should return a new A() or a new B(). The string I recieved
as argument will have enough information for me to decide which object
to be returned. How would i do it.

My environment: VS2003 on Windows XP.

All your helps appreciated

Apr 2 '07 #1
5 2235
Don't forget to #include <string>
You could always use ... is it typeid? http://www.cplusplus.com/doc/tutorial/typecasting.html
Search for typeid
int main( void )
{
char cone;

if( typeid( cone ) == typeid( char ) )
std::cout<< "Woot!";
else
std::cout<< "Not char!";
return 0;
}
as an example

Apr 2 '07 #2
On 2007-04-02 19:40, raan wrote:
What I am trying to achieve here is depicted in the small program
below.

// Wrapit.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <map>
#include <list>

using namespace std;

class A
{

private:
string a;
string b;
string c;
public:
A(){}

};

class B
{

private:
string a;
string b;
string c;

public:
B(){cout << "B constructor is being called \n";}
};
class C
{
private:
map<string, A * aobj;
map<string, B * bobj;
public:

C(){cout << "Constructor of C called \n";}

template <class T>
T& operator [] (string key)
{
cout << "Operator [] called \n";
return new A(); //if the key has a particular text in it return
new A
// otherwise return new B();
}

};

int _tmain(int argc, _TCHAR* argv[])
{
C c;
c["abcd"] = new A();
c["efgh"] = new B();

return 0;
}
Obviously the above program will give you compiler errors.

I am trying to put a wrapper around the maps. And the insertion to the
maps is done through an
(eg . c["abcd"] = new A()) overloaded [] operator. Further I want to
use just one [] version of the function, but inside I will determine
whether I should return a new A() or a new B(). The string I recieved
as argument will have enough information for me to decide which object
to be returned. How would i do it.
I'm 99.99% sure you can't. Not unless you make both A and B inherit from
a common base-class and return that. You must remember that templates
are compile-time constructs so they can't depend on anything that isn't
known at compiletime.

--
Erik Wikström
Apr 2 '07 #3
raan wrote:
What I am trying to achieve here is depicted in the small program
below.

// Wrapit.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <map>
#include <list>

using namespace std;

class A
{

private:
string a;
string b;
string c;
public:
A(){}

};

class B
{

private:
string a;
string b;
string c;

public:
B(){cout << "B constructor is being called \n";}
};
class C
{
private:
map<string, A * aobj;
map<string, B * bobj;
public:

C(){cout << "Constructor of C called \n";}

template <class T>
T& operator [] (string key)
{
cout << "Operator [] called \n";
return new A(); //if the key has a particular text in it return
new A
// otherwise return new B();
}

};

int _tmain(int argc, _TCHAR* argv[])
{
C c;
c["abcd"] = new A();
c["efgh"] = new B();

return 0;
}
Obviously the above program will give you compiler errors.

I am trying to put a wrapper around the maps. And the insertion to the
maps is done through an
(eg . c["abcd"] = new A()) overloaded [] operator. Further I want to
use just one [] version of the function, but inside I will determine
whether I should return a new A() or a new B(). The string I recieved
as argument will have enough information for me to decide which object
to be returned. How would i do it.

My environment: VS2003 on Windows XP.

All your helps appreciated
There are a couple issues with your code:
1) assuming your [] operator works, the return type is a temporary const
T & that cannot be assignee.
2) it's awkward to really tell the compiler to pick up the template
argument, check the following code:
#include <map>
#include <list>
#include <iostream>

using namespace std;

class A
{

private:
string a;
string b;
string c;
public:
A(){}

};

class B
{

private:
string a;
string b;
string c;

public:
B(){cout << "B constructor is being called \n";}
};
class C
{
private:
map<string, A * aobj;
map<string, B * bobj;
public:

C(){cout << "Constructor of C called \n";}

template <class T>
T* at (string key)
{
cout << "Operator [] called \n";
return new A(); //if the key has a particular text in it returnnew A
// otherwise return new B();
}
template <class T>
T* operator [] (string key)
{
cout << "Operator [] called \n";
return new A(); //if the key has a particular text in it returnnew A
// otherwise return new B();
}

};
#define _tmain main
#define _TCHAR char

int _tmain(int argc, _TCHAR* argv[])
{
C c;
A* a = c.at<A>("abcd");
A* aa = c.operator[]<A>("abcd");
// c.get<B>["efgh"] = new B();

return 0;
}

Apr 2 '07 #4
There are a couple issues with your code:
1) assuming your [] operator works, the return type is a temporary const
T & that cannot be assignee.
2) it's awkward to really tell the compiler to pick up the template
argument, check the following code:
I did some rethinking. following is what I really want.

#include "stdafx.h"
#include <map>
#include <list>

using namespace std;

class A
{

private:
string a;
string b;
string c;
public:
A(){}


};

class B
{

private:
string a;
string b;
string c;

public:
B(){cout << "B constructor is being called \n";}
};
class C
{
private:
map<string, A * aobj;
map<string, B * bobj;
string cur_key; //store the current key here till a
//valid = operator is called.
public:

C(){cout << "Constructor of C called \n";}

//Get the current key for the map.
string operator [] (string key)
{
cur_key = key;
cout << "Operator [] called " << key.c_str() << endl;
return key;
}

//Insert object A into aobj map with the key stored in cur_key
int operator = (A* a)
{
aobj.insert(make_pair(cur_key, a));
cout << "Operator = A* called \n";
return 1; //Should be an iterator object
}

//insert object B into bobj map with the key stored in cur_key
int operator = (B *b)
{
cout << "Operator = B* called \n";
}
};

int _tmain(int argc, _TCHAR* argv[])
{
C c;
A *a = new A();
c["abcd"] = a;
return 0;
}

As you can see, c["abcd"] will call the [] operator and set the
current key. Then the overloaded assignment operator is called to
insert the object into relevant maps.

The problem is that it won't compile. It gives an error.
error C2679: binary '=' : no operator found which takes a right-hand
operand of type 'A *' (or there is no acceptable conversion)

What is that I am doing wrong here.

~raan
Apr 2 '07 #5
raan wrote:
>[..store the key and act apon it in operator=..]
What you need is a custom "assigner" object returned from
the operator[]. That object's operator= will actually perform
the insertion.

class C {
...
public:
class MapAssigner {
C& self;
public:
MapAssigner(C& me) : self(me) {}
void operator=(A* pA) {
self.aobj.insert(std::make_pair(self.cur_key, pA));
}
void operator=(B* pB) {
self.bobj.insert(std::make_pair(self.cur_key, pB));
}
};

MapAssigner operator[](std::string const& key) {
cur_key = key;
return MapAssigner(*this);
}
};

Now, where and when you want to do the validation of the 'cur_key'
is up to you.

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Apr 2 '07 #6

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

17 posts views Thread by Terje Slettebø | last post: by
15 posts views Thread by Steve | last post: by
10 posts views Thread by olson_ord | last post: by
51 posts views Thread by Pedro Graca | last post: by
3 posts views Thread by md | last post: by
8 posts views Thread by mural | last post: by
3 posts views Thread by mural | last post: by
6 posts views Thread by josh | last post: by
4 posts views Thread by gvr123 | last post: by
5 posts views Thread by ashu | last post: by
1 post views Thread by Waqarahmed | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.