Archived

This topic is now archived and is closed to further replies.

CGameProgrammer

Conversion Operators, but with Templates

Recommended Posts

My problem is a bit complicated. Basically, I want to be able to convert to any type imaginable through a templated conversion operator. First I''ll illustrate a typical operator:
  
template <class T> class CObject
{
    public:
 
        operator float ( )
        {
            return (float)m_Data;
        }
 
        T m_Data;
};
 
void main ( )
{
    CObject<int> O;
    float F;
 
    O.m_Data = 43;
    F = O; // This calls operator float()

}
  
Conversion operators are called automatically when a type is tried to be converted into another type. Saying F = O converts the CObject<int> O into a float by calling the operator. By the way, don''t worry about the apparent lack of purpose in making O a CObject<int> and then converting it to float... I just do that as an example. Now, what I want to do is be able to write a conversion operator for any type, by taking advantage of templates. My reason for this is very complicated and I won''t go into it, but I wrote the conversion operator looking like this:
  
template <class T> class CObject
{
    public:
 
        template <class C> operator C ( )
        {
            return (C)m_Data;
        }
 
        T m_Data;
};
  
That seems to compile just fine, but I can''t figure out the correct syntax for calling such an operator. So what would be the correct replacement for "F = O" to work with that operator? BTW, another acceptable operator would be this:
  
template <class T> class CObject
{
    public:
 
        template <class C> C operator () ( )
        {
            return (float)m_Data;
        }

        T m_Data;
};
  
The non-template version of that operator would be called like:
  
F = O();
  
But I don''t know about the template version. Any ideas? ~CGameProgrammer( );

Share this post


Link to post
Share on other sites
By the way, the reason I don''t just say F = (float)O.m_Data is because m_Data isn''t actually directly accessable in the real code; it''s private. Of course, I can say:
  
template <class T> class CObject
{
public:

operator = ( T Data ) { m_Data = Data; }
T GetData ( ) { return m_Data; }

private:

T m_Data;
};

void main ( )
{
CObject<int> O;
float F;

O = 43;
F = (float)O.GetData( );
}

...but I don''t like having to say "O.GetData()". You can see I don''t use O.SetData(). I wanted something simpler, either the operator C or the operator ().

So I don''t care merely about the ends, but also about the means.

~CGameProgrammer( );

Share this post


Link to post
Share on other sites
Well, first let me point out one obvious thing - built-in types can be automatically converted with static_cast, but maybe only your example is showing long and float etc.

If you want to _store_ an arbitrary type i''d look into boost::any which you can read up on at www.boost.org
There is some detailed explanation about how it works there as well.

However, I think what you''re really talking about is a Variant type of class where any stored type can be tried to be converted to another type.

This is a bit more complicated and there are several examples of attempts at this. You may want to check out the C/C++ Users Journal.

Also, although this sort of defeats the purpose of your question, if your read Meyer''s Effective C++ ( or More Effective C++ ) he gives some good reasons as to why you should avoid implicit conversion operatiors - which is what you are trying to make.

They can cause many temporary objects to get created unexpectedly.

He suggests using an explicit conversion method - eg a class method that converts to the type.

Look up some stuff on Variants and you will likely find something like what you are looking for.
Sorry I don''t remember enough about implementing them off the top of my head...

Share this post


Link to post
Share on other sites
However, I think what you''re really talking about is a Variant type of class where any stored type can be tried to be converted to another type

Yes, exactly. Specifically, the actual class I''m using is a member-variable class, like CMember<CCamera> m_Camera;, and it should be able to support conversion to other types, like CVector Position = (CVector)m_Camera.

Because member variables can potentially be any type, obviously CMember can''t be aware of them all and have explicit conversion operators for them all.

~CGameProgrammer( );

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
did you try the obvious? Just assign and from what I understand the correct conversion operator should be invoked. When you use templated classes (such as vector) you have to say that you are using a specific type. When using templated functions the compiler takes care of it for you. Otherwise functions like sort would be harder to use. So just use the code that you have written and try it out. It should work.

Share this post


Link to post
Share on other sites
You must specify the template argument when using templates. The compiler actually makes an error saying this if I leave it out.

But actually, I no longer really need to do this. Even if it were possible to make a template operator, using it would still require more arguments than simply saying F = (float)O(), so that's what I now do. O() is T operator () () { return m_Data; }. So there really was no reason to try to use a template operator.

EDIT: The other way to do it is F = (float)int(O) though that's longer. And actually, in the case of primitives, I can say F = (float)O which automatically calls the int conversion operator, then converts to float. But that only works for primitives.

~CGameProgrammer( );



Edited by - CGameProgrammer on January 10, 2002 2:30:50 PM

Share this post


Link to post
Share on other sites