473,323 Members | 1,570 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,323 software developers and data experts.

Typecasting operator on simple types vs. classes

Hi! I'm having a little trouble with the typecast operator, can anybody
help me with the rules for when the this operator is invoked?

In the class 'Test' in the code below, the typecast operator returns a
'mytype'. In main() I use the [] operator on 'Test'-class objects. If
'mytype' is a pointer the [] operator works fine. But if I instead try
to call an overloaded [] operator, the typecast operator is not invoked,
and I get a compiler error (unless I make an explicit cast.) So does the
'operator mytype ()' only work properly with simple types?

Any help would be appreciated!

Nico

template <class mytype>
class Test
{
mytype i;

public:

operator mytype () {return i;}
};

class Test2
{
public:
int operator [] (int i) {return i;}
};

int main(void)
{
Test<double*> t1;
Test<Test2> t2;

t1[0]; // This line works fine
t2[0]; // This line doesn't compile
((Test2)t2)[0]; // This also works

return 0;
}

Jul 19 '05 #1
7 4505
Nicolay Korslund wrote:

<SNIP>
In the class 'Test' in the code below, the typecast operator returns a
'mytype'. In main() I use the [] operator on 'Test'-class objects. If
'mytype' is a pointer the [] operator works fine. But if I instead try
to call an overloaded [] operator, the typecast operator is not invoked,
and I get a compiler error (unless I make an explicit cast.) So does the
'operator mytype ()' only work properly with simple types? <SNIP>
template <class mytype>
class Test
{
mytype i;

public:

operator mytype () {return i;}
};

class Test2
{
public:
int operator [] (int i) {return i;}
};

int main(void)
{
Test<double*> t1;
Test<Test2> t2;

t1[0]; // This line works fine
t2[0]; // This line doesn't compile
((Test2)t2)[0]; // This also works

return 0;
}


There is a rule that in a conversion sequence only one use-defined
conversion operator is allowed.
My guess is that the rule covers overloaded operators too.
t1[0] works because there is only one use-defined conversion is involved :
operator mytype () {return i;}
It returns object of double* type for which built-in [] operator is defined.
t2[0], however, casts through the above user-defined conversion to Test2
type, which, in turn, has only use-defined [] operator. Of course, when you
remove one of user-defined operators from implicit sequence by explicit
typecasting, everything works: ((Test2)t2)[0]

I would suggest adding [] operator to the *Test* class, like this

int operator[](int ind) {return i[ind];}

Then you don't have to think about typecasting.

Nikolai Borissov
Jul 19 '05 #2
Nikolai Borissov wrote:
Nicolay Korslund wrote: I would suggest adding [] operator to the *Test* class, like this

int operator[](int ind) {return i[ind];}

Then you don't have to think about typecasting.


Except that t1[0] returns a double and t2[0] returns an int.

I'm thinking the other answer is a proxy class.

Jul 19 '05 #3
Nicolay Korslund wrote:
Hi! I'm having a little trouble with the typecast operator, can anybody
help me with the rules for when the this operator is invoked?

In the class 'Test' in the code below, the typecast operator returns a
'mytype'. In main() I use the [] operator on 'Test'-class objects. If
'mytype' is a pointer the [] operator works fine. But if I instead try
to call an overloaded [] operator, the typecast operator is not invoked,
and I get a compiler error (unless I make an explicit cast.) So does the
'operator mytype ()' only work properly with simple types?

Any help would be appreciated!

Nico

template <class mytype>
class Test
{
mytype i;

public:

operator mytype () {return i;}
};

class Test2
{
public:
int operator [] (int i) {return i;}
};

int main(void)
{
Test<double*> t1;
Test<Test2> t2;

t1[0]; // This line works fine
t2[0]; // This line doesn't compile
((Test2)t2)[0]; // This also works

return 0;
}


I'm not sure why the code above does not work. There seems to be only
one conversion operator and one operator[] definition. I looked through
the copy of the standard I have and it is unfortunatly very wordy about
the subject and hard to filter the relevant pieces.
This is another version of your example that does work. (at least on gcc
3.3.1).
template <class mytype> class TestProxy;

template <class mytype>
class Test
{
friend class TestProxy<mytype>;
mytype v;

public:

operator mytype & ()
{
return v;
}

TestProxy<mytype> operator [] (int i);

};

template <typename T>
class PtrType
{
public:
typedef int Type; // HACK ALERT
};

template <typename T>
class PtrType<T*>
{
public:
typedef T & Type;
};

template <class mytype> class TestProxy
{
public:

Test<mytype> & m_test;
int m_i;

TestProxy( Test<mytype> & i_test, int i )
: m_test( i_test ),
m_i( i )
{
}

operator typename PtrType<mytype>::Type ()
{
return m_test.v[m_i];
}
};

template <class mytype>
inline TestProxy<mytype> Test<mytype>::operator [] (int i)
{
return TestProxy<mytype>( *this, i );
}

class Test2
{
public:
int operator [] (int i)
{
return i;
}

};

int main(void)
{
Test<double*> t1;
Test<Test2> t2;

t1[1]; // This line works fine
int x = t2[2]; // This line doesn't compile
((Test2)t2)[3]; // This also works

return 0;
}

Jul 19 '05 #4
Gianni Mariani wrote:
Nikolai Borissov wrote:
Nicolay Korslund wrote:
I would suggest adding [] operator to the *Test* class, like this

int operator[](int ind) {return i[ind];}

Then you don't have to think about typecasting.


Except that t1[0] returns a double and t2[0] returns an int.


That's right, because t1 and t2 are objects of different type. It's already
not a technical matter, rather a design one.
OP is supposed to know the purpose of his design. Maybe t1[] being of type
int and t2[] of type double is exactly what he wants.
I'm thinking the other answer is a proxy class.


And I'm thinking about Occum's Razor:

"Entities must not be multiplied beyond what is necessary"

Here's an original Latin version:

"Pluralitas non est ponenda sine neccesitate"

Nikolai Borissov
Jul 19 '05 #5
Nikolai Borissov wrote:
Gianni Mariani wrote:
Nikolai Borissov wrote:
Nicolay Korslund wrote:
I would suggest adding [] operator to the *Test* class, like this

int operator[](int ind) {return i[ind];}

Then you don't have to think about typecasting.


Except that t1[0] returns a double and t2[0] returns an int.

That's right, because t1 and t2 are objects of different type. It's already
not a technical matter, rather a design one.
OP is supposed to know the purpose of his design. Maybe t1[] being of type
int and t2[] of type double is exactly what he wants.
I'm thinking the other answer is a proxy class.

And I'm thinking about Occum's Razor:

"Entities must not be multiplied beyond what is necessary"


The counter is the Mariani conjecture.

"unneccessarily complex solutions are a product of adopting
unneccessarily simple tools".

Here is the orginal in English.

If you use tools too simple for the given task you will end up with a
solution that is more complex than neccassary.

Here's an original Latin version:

"Pluralitas non est ponenda sine neccesitate"


Jul 19 '05 #6

Gianni Mariani wrote:
The counter is the Mariani conjecture.

"unneccessarily complex solutions are a product of adopting
unneccessarily simple tools".

Here is the orginal in English.

If you use tools too simple for the given task you will end up with a
solution that is more complex than neccassary.


Good addendum to Occum's Razor :))

I've realized what's the problem with returning correct type.
Should be interesting to think about it the other day (just don't have time
now).
I'll analyze your solution too.

Ciao

Nikolai Borissov
Jul 19 '05 #7
> I've realized what's the problem with returning correct type.
Should be interesting to think about it the other day (just don't have time
now).
I'll analyze your solution too.


Ok, thank you both for the help.

Nicolay

Jul 19 '05 #8

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

5
by: Vijai Kalyan | last post by:
Hello, I have come back to C++ after a couple of years with Java so I am quite rusty and this question may seem poor: My platform is Windows XP with MSVC 7.1. I have a class with a...
20
by: Patrick Guio | last post by:
Dear all, I have some problem with insertion operator together with namespace. I have a header file foo.h containing declaration of classes, typedefs and insertion operators for the typedefs in...
11
by: Vinod Patel | last post by:
I have a piece of code : - void *data; ...... /* data initialized */ ...... struct known_struct *var = (struct known_struct*) data; /*typecasting*/ How is this different from simple...
5
by: Peter Seaman | last post by:
I do recognise a number of very appealing features of C#, in particular the strong typing and the need in some contexts to be very explicit regarding your intention. But the most common operator -...
7
by: Raghu | last post by:
Hello All, I need some help regarding overloading operation. Is there any way to overload typecasting? I mean if i have a piece of code as below. int a = 2: float b; b = (float)a;
6
by: Bill foust | last post by:
I'm running into a situation there I think an operator overload would solve the issue, but I'm unable to make it work for some reason. If anyone can help here I would appreciate it. I have a...
6
by: Nishu | last post by:
Hi all, What is difference between typecasting and casting? I used to think that both are same; but few days back someone pointed out here that these are different. Vague guess, Is it that...
14
by: Hunk | last post by:
Hi I ws wondering if there is a way to implement operator+ in case of virtual classes. Here's the problem. I have to have a base string class from which two classes (normal char string and a...
19
by: C++Liliput | last post by:
I have a custom String class that contains an embedded char* member. The copy constructor, assignment operator etc. are all correctly defined. I need to create a map of my string (say a class...
0
by: DolphinDB | last post by:
Tired of spending countless mintues downsampling your data? Look no further! In this article, you’ll learn how to efficiently downsample 6.48 billion high-frequency records to 61 million...
0
by: ryjfgjl | last post by:
ExcelToDatabase: batch import excel into database automatically...
0
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
1
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
0
by: Vimpel783 | last post by:
Hello! Guys, I found this code on the Internet, but I need to modify it a little. It works well, the problem is this: Data is sent from only one cell, in this case B5, but it is necessary that data...
0
by: jfyes | last post by:
As a hardware engineer, after seeing that CEIWEI recently released a new tool for Modbus RTU Over TCP/UDP filtering and monitoring, I actively went to its official website to take a look. It turned...
1
by: PapaRatzi | last post by:
Hello, I am teaching myself MS Access forms design and Visual Basic. I've created a table to capture a list of Top 30 singles and forms to capture new entries. The final step is a form (unbound)...
1
by: Defcon1945 | last post by:
I'm trying to learn Python using Pycharm but import shutil doesn't work
1
by: Shællîpôpï 09 | last post by:
If u are using a keypad phone, how do u turn on JavaScript, to access features like WhatsApp, Facebook, Instagram....

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.