Creating a weak type class

S

Simon

Hi,

First of all I am not sure if the term 'weak type' is the right one.
But basically this is what I have:

// ------------------------------
#include "string.h"
#include <sstream>

class Weak
{
public:
Weak() : _d64Bit(0) {};
Weak( double d ){
_d64Bit = d;
std::eek:stringstream o;
if ((o << d))
{
_sString = o.str();
}
}
Weak( const std::string& s ){
_d64Bit = atof( s.c_str() );
_sString = s;
}
Weak( const Weak& w ){
_d64Bit = w._d64Bit;
_sString = w._sString;
}
~Weak(){
}

Weak operator+( const Weak& data ) const{
double d = data._d64Bit + _d64Bit;
return Weak( d );
}

private:
double _d64Bit;
std::string _sString;
};

int main(int argc, TCHAR* argv[])
{
// this works as expected
Weak x = 5;
Weak y = "37";
Weak z = x + y;

// but this does not work.
Weak z1 = 5 + "37"; // = "42" && 42
}
// ------------------------------

How can I get the last operation to work?
I get no errors, the result is just "0" and 0.00

Many thanks

Simon
 
F

Frank Bergemann

Hi Simon,
   // but this does not work.
   Weak z1 = 5 + "37"; // = "42" && 42}

I thought it is a simple explanation.
But when i tested it, i was wondering about the results a bit.

First this:
It doesn't work as you expect, because the right side evaluation of

5 + "37"

....is done, without considering the target variable and it's type.
You're wrong assuming, that both operands are converted to type 'Weak'
before applying the + operator.

So you need to do it this way:

Weak z1 = Weak(5) + "37";

This forces to use type Weak for the operand 5 first
and use the + operator of Weak for adding "37" next.
Then it will apply your conversion constructor for the "37"
to make it a Weak as well.

However if i run a sample program like this:

#include <iostream>
using namespace std;

int main(int, char**)
{
int a = 1;
cout << "result is: " << (a + "37") << endl;
return 0;
}

.... i wonder about the resulting output:

frank@frank-desktop:~/TEST$ ./sample
result is: 7

Seems it starts with the operand "37" first
and adds #1 as an offset to the string "37" next.
I guess, this is because there is no
operator+(char*)
for int.
But a operator++(int) for char* (or std:string)
???

rgds,
Frank
 
J

James Kanze

First of all I am not sure if the term 'weak type' is the
right one. But basically this is what I have:
// ------------------------------
#include "string.h"
#include <sstream>
class Weak
{
public:
Weak() : _d64Bit(0) {};
Weak( double d ){
_d64Bit = d;
std::eek:stringstream o;
if ((o << d))
{
_sString = o.str();
}
}
Weak( const std::string& s ){
_d64Bit = atof( s.c_str() );

I can't get this to compile without including stdlib.h.
_sString = s;
}
Weak( const Weak& w ){
_d64Bit = w._d64Bit;
_sString = w._sString;
}
~Weak(){
}
Weak operator+( const Weak& data ) const{
double d = data._d64Bit + _d64Bit;
return Weak( d );
}
private:
double _d64Bit;
std::string _sString;
};
int main(int argc, TCHAR* argv[])

And I have to replace TCHAR with char for this to compile. (I
don't know what you're using as a compiler, but it certainly
isn't standard if TCHAR is somehow predefined or a keyword.)
{
// this works as expected
Weak x = 5;
Weak y = "37";
Weak z = x + y;
// but this does not work.
Weak z1 = 5 + "37"; // = "42" && 42}

That's because it contains undefined behavior. You can't add 5
to the address of an array that is only three elements long.

In practice, however, I don't think it should compile. If the
expression were:
Weak z1 = 2 + "37" ;
for example, there's no undefined behavior, but a compiler
diagnostic is required (because in order to compile, two user
defined conversions are necessary). And neither this nor your
original statement compile with my compiler (g++ 4.3.2 is the
only compiler I have handy on this machine). The conversion of
the initializer expression requires two user defined
conversions.

Note, however, that:
Weak z1( 5 + "37" ) ;
does compile (but still contains undefined behavior), and
Weak z1( 1 + "37" ) ;
compiles, and results in z1 having the value of 7.
// ------------------------------
How can I get the last operation to work?

First, define what you mean by "work":). If it's what I
suspect (and you expect 42 as a result), you can't. You're
adding an array, which decays to a pointer and an integral type,
and adding an integral type to a pointer has a fully defined
meaning in the standard, and can't be overloaded. You can't
overload anything that doesn't involve user defined types.
Ever.
I get no errors, the result is just "0" and 0.00

If you get no errors, it's time to change compilers (or maybe
just invoke the compiler correctly). With the exact code you
posted, I get three errors, and at least two are required
diagnostics. If you don't get an error with the declaration of
z1, that's a serious error in the compiler, and (probably) not a
case of some extension accidentally being activated.
 
J

James Kanze

[...]
However if i run a sample program like this:
#include <iostream>
using namespace std;
int main(int, char**)
{
int a = 1;
cout << "result is: " << (a + "37") << endl;
return 0;
}
... i wonder about the resulting output:
frank@frank-desktop:~/TEST$ ./sample
result is: 7
Seems it starts with the operand "37" first
and adds #1 as an offset to the string "37" next.
I guess, this is because there is no
operator+(char*)
for int.

It's because there *is* a built-in operator+( int, char const*
). Which returns a char const*. C++ supports all of the
pointer arithmetic from C.
 
B

Bart van Ingen Schenau

Frank said:
Hi Simon,


I thought it is a simple explanation.

It is a simple explanation: Both 5 and "37" have a primitive type (int
and const char[3] respectively) and there is already a defined meaning
for operator+(int, const char*).
But when i tested it, i was wondering about the results a bit.

First this:
It doesn't work as you expect, because the right side evaluation of

5 + "37"

...is done, without considering the target variable and it's type.
You're wrong assuming, that both operands are converted to type 'Weak'
before applying the + operator.

So you need to do it this way:

Weak z1 = Weak(5) + "37";

This forces to use type Weak for the operand 5 first
and use the + operator of Weak for adding "37" next.
Then it will apply your conversion constructor for the "37"
to make it a Weak as well.

However if i run a sample program like this:

#include <iostream>
using namespace std;

int main(int, char**)
{
int a = 1;
cout << "result is: " << (a + "37") << endl;
return 0;
}

... i wonder about the resulting output:

frank@frank-desktop:~/TEST$ ./sample
result is: 7

Seems it starts with the operand "37" first
and adds #1 as an offset to the string "37" next.

That is right, because 'a' has the value 1.
I guess, this is because there is no
operator+(char*)
for int.
But a operator++(int) for char* (or std:string)
???

No, you are seeing basic pointer arithmetic, using operator+(int, const
char*).
rgds,
Frank

Bart v Ingen Schenau
 

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

Similar Threads


Members online

No members online now.

Forum statistics

Threads
474,159
Messages
2,570,879
Members
47,417
Latest member
DarrenGaun

Latest Threads

Top