std:map inheritance with MFC problem

D

Donkeylung

I have a base class which has a protected member:
map<mstring,mstring>
mstring is a derived class from std::string, which includes some
functionality to cope with MFC.

It works fine in the base class, but when I try to use it in a derived
class, it gives me an error message.

C:\Program Files\Microsoft Visual Studio .NET
2003\Vc7\include\functional(139): error C2678: binary '<' : no operator
found which takes a left-hand operand of type 'const mstring' (or there
is no acceptable conversion)

In my class there is an operator < overload. I took that out to see it
that could be the problem, but I get the same message. I then tried a
test map<string,string> and I get the same message. I tried messing
with map < mstring, mstring > (adding the spaces, because sometimes
with a template of containers VC++ needs certain spaces). Nothing.

The funny thing is that if I use the mfc CString class instead, it
works, but I don't want to redo the extra functionality deriving from
CString.

Any help?

Thanks,
Jay
 
A

Aleksander Beluga

Donkeylung said:
C:\Program Files\Microsoft Visual Studio .NET
2003\Vc7\include\functional(139): error C2678: binary '<' : no operator
found which takes a left-hand operand of type 'const mstring' (or there
is no acceptable conversion)

In my class there is an operator < overload.

Can you please show two things:
1) How you derive from std::string?
2) How do you implement operator < in mstring?
3) How do you use map in case of std::string possession?
 
D

Donkeylung

1)
typedef class mfc_string :
public string
{
.....
}mstring;


2)
Here are the 2 operator < overloads (they originally did not take
const arguments either way, I still get the error)
mfc_string mfc_string::eek:perator<(const mfc_string& p)
{
double left = atof(this->c_str());
double right = atof(p.c_str());
char enter_string[50];
sprintf(enter_string, "%f", left-right);
return mstring(enter_string);
}

mfc_string mfc_string::eek:perator<(const double& right)
{
double left = atof(this->c_str());
char enter_string[50];
sprintf(enter_string, "%f", left-right);
return mstring(enter_string);
}

3) When I used map<string, string>, it was only for a test.

Another note, the error only occurs when I use the [] notation. It
doesn't matter if it is accessing a previously defined key(in the base
class, where it is fine) or if is creating a new key in the derived
class.

thanks,
jay
 
L

loufoque

Donkeylung a écrit :
mstring is a derived class from std::string

std::string isn't meant to be derived, it doesn't have any virtual function.
Thus you will probably have issues if you try doing that.
 
A

Aleksander Beluga

Donkeylung said:
Another note, the error only occurs when I use the [] notation. It
doesn't matter if it is accessing a previously defined key(in the base
class, where it is fine) or if is creating a new key in the derived
class.

Hmmm, what about inserting new pair? Does it work?

Can you please try the following code that's trying to model your
problem on your compiler. I have a slight guess that it is a bug/feature
of VC7.0.

#include <map>
#include <string>

typedef class mfc_string : public std::string
{
public:
int size;

} mstring;
int main()
{
std::map<mstring,mstring> a;
mstring b;
a.size = 1;
}//main

This code compiled correctly on compilers I currently have access to:
Comeau, GCC 3.4 (MinGW), VC++8.

If problem is in compiler we'll try to think of a workaround that could
be applied.
 
J

Jeff Flinn

Donkeylung said:
I have a base class which has a protected member:
map<mstring,mstring>
mstring is a derived class from std::string, which includes some
functionality to cope with MFC.

It works fine in the base class, but when I try to use it in a derived
class, it gives me an error message.

C:\Program Files\Microsoft Visual Studio .NET
2003\Vc7\include\functional(139): error C2678: binary '<' : no
operator found which takes a left-hand operand of type 'const
mstring' (or there is no acceptable conversion)

Do you have:

bool operator<( const mstring&, const mString& );

or
bool mstring::eek:perator<( const mString& )const;

In my class there is an operator < overload. I took that out to see
it that could be the problem, but I get the same message. I then
tried a test map<string,string> and I get the same message. I tried

Did you properly #include <string>, notice the lack of .h? You must have a
'using namespace std;' in there as well somewhere, just an assumption as
you've neglected to post a single line of actual code.

Jeff Flinn
 
A

Aleksander Beluga

loufoque said:
Donkeylung a écrit :

std::string isn't meant to be derived, it doesn't have any virtual
function.
Thus you will probably have issues if you try doing that.

Interface derives even if parent has no virtual functions. Not having a
virtual functions, IMHO, is not a reason to rewrite all the work that's
been accomplished by STL creators for a sake of adding one-two-three
tiny functions.
 
B

Bob Hairgrove

Interface derives even if parent has no virtual functions. Not having a
virtual functions, IMHO, is not a reason to rewrite all the work that's
been accomplished by STL creators for a sake of adding one-two-three
tiny functions.

Just be sure never to allow anyone to delete a mfc_string through a
pointer to std::string. Since std::string has no virtual destructor,
this would invoke undefined behavior.
 
B

Ben Pope

Aleksander said:
Interface derives even if parent has no virtual functions. Not having a
virtual functions, IMHO, is not a reason to rewrite all the work that's
been accomplished by STL creators for a sake of adding one-two-three
tiny functions.

It's unsafe if somebody tries to delete one through the base pointer.

IMO, it's better to have std::string as a member (which is the preferred
form of code reuse) and then provide a constructor from std::string, a
conversion operator to std::string, and wrap any other functions you
feel necessary. Yes, it's hassle, but it does prevent users from
inadvertently invoking undefined behaviour.

Ben Pope
 
A

Aleksander Beluga

Bob said:
Just be sure never to allow anyone to delete a mfc_string through a
pointer to std::string. Since std::string has no virtual destructor,
this would invoke undefined behavior.

Not even an UB, just a little memory leak :)
 
P

peter koch

Aleksander said:
Not even an UB, just a little memory leak :)

No - it is UB, but could very well result in a small memory leak. It
could also result in having your heap corrupted, in terminating your
program or in other less likely behaviours.

/Peter
 
N

Neil Cerutti

1)
typedef class mfc_string :
public string
{
....
}mstring;


2)
Here are the 2 operator < overloads (they originally did not take
const arguments either way, I still get the error)
mfc_string mfc_string::eek:perator<(const mfc_string& p)

mfc_string mfc_string::eek:perator<(const double& right)

You should return a bool from operator<, not a copy of the lesser
mfc_string. If (*this) is less than right, return true, otherwise return
false.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,432
Messages
2,571,680
Members
48,796
Latest member
Greg L.

Latest Threads

Top