Template casting operator

M

Makhno

Hello,
Why does my cast from Vector<class Float> to Vector<float> not work? It
won't compile,

template<class Float> class Vector
{
public:
Vector(Float x1,Float y1,Float z1):x(x1),y(y1),z(z1){}
inline Vector<float> operator() () const;

Float x,y,z;
};

template <class Float> inline Vector<float>
Vector<Float>::eek:perator() () const
{
return Vector<float>((float)x,(float)y,(float)z);
}


int main()
{
Vector<double> pd(5.6,3.4,2.4);

Vector<float> pf=(Vector<float>)pd; /* compiler error here */

}

I'd ideally like to be able to cast a Vector<double> to a Vector<float>.
 
V

Victor Bazarov

Makhno said:
Why does my cast from Vector<class Float> to Vector<float> not work?

Because you didn't use the operator() you wrote. But that's not what
bothers you, is it? Conversion from Vector<type1> to Vector<type2>
is something that can be easily obtained, given the right function.
See below.
It
won't compile,

template<class Float> class Vector
{
public:
Vector(Float x1,Float y1,Float z1):x(x1),y(y1),z(z1){}
inline Vector<float> operator() () const;

Declaring something 'inline' without providing its body is useless.

Back to your problem... You probably wanted to create a templated
type conversion operator:

template said:
Float x,y,z;
};

template <class Float> inline Vector<float>
Vector<Float>::eek:perator() () const
{
return Vector<float>((float)x,(float)y,(float)z);
}

Make this

template<class F> template<class D>
Vector<F>::eek:perator Vector<D>() const
{
int main()
{
Vector<double> pd(5.6,3.4,2.4);

Vector<float> pf=(Vector<float>)pd; /* compiler error here */

Try it now.
}

I'd ideally like to be able to cast a Vector<double> to a Vector<float>.

C-style casts are unnecessary if proper conversion is provided.

---------------------------- code that compiles -------------------------
template<class F> class Vector
{
public:
Vector(F x1, F y1, F z1):x(x1),y(y1),z(z1){}
template<class D> operator Vector<D> () const;
F x,y,z;
};

template <class F> template<class D>
Vector<F>::eek:perator Vector<D> () const
{
return Vector<D>(x,y,z);
}

int main()
{
Vector<double> pd(5.6,3.4,2.4);
Vector<float> pf = pd; /* no compiler error here */
}
 
J

Jonathan Turkanis

Victor Bazarov said:

Back to your problem... You probably wanted to create a templated
type conversion operator:

template<class S> operator Vector<S>() const;

Your diagnosis is correct, of course, and you solution works, but
wouldn't it be more natural to define a converting constructor in this
case?

I'd write a conversion operator if I was not able to modify the
definition of the target type (e.g. converting to int or a pointer
type) or if I by using an operator I could avoid constucting a new
object (e.g. by returning a reference to a member.) With conversions
between specializations of the same template, I'd tend to use a
converting constructor.

Jonathan
 
M

Makhno

Declaring something 'inline' without providing its body is useless.

Do you mean putting 'inline' in the declaration is useless, or are you
refering to how I've put the word 'inline' in both the declaration and
definition? (a habbit I got into when VS6 once acted strange unless I did
this)
---------------------------- code that compiles -------------------------

Afraid not. I get "unrecognizable template declaration/definition" from
..NET, then a ton of other errors. But it is the kind of thing I'm looking
for, just didn't know how to get the syntax correct.
 
V

Victor Bazarov

Makhno said:
Do you mean putting 'inline' in the declaration is useless, or are you
refering to how I've put the word 'inline' in both the declaration and
definition? (a habbit I got into when VS6 once acted strange unless I did
this)

'inline' is but a suggestion to the compiler. The compiler is free to
completely ignore it. Given that you put it in a declaration, what should
a compiler do when it sees a call to the function? Where would the compiler
take the body necessary to make an inline function expansion? So, adding
'inline' to a declaration is meaningless and is probably simply ignored by
the compiler.

Supplying 'inline' with the definition is perfectly fine and is usually
done when the definition is in the same header but outside the class, mind
you, without 'inline' in such case you are likely to have a multiple
definition error (if you happen to use that header in more than one
translation unit).
compiles -------------------------
Afraid not. I get "unrecognizable template declaration/definition" from
.NET, then a ton of other errors. But it is the kind of thing I'm looking
for, just didn't know how to get the syntax correct.

Contact VC++ people, then. It is quite possible they haven't got their
compiler ready for the real world yet. When I write "compiles", I make sure
to test it.

Good luck!

Victor
 
J

Jonathan Turkanis

Makhno said:
useless.


Afraid not. I get "unrecognizable template declaration/definition" from
.NET, then a ton of other errors. But it is the kind of thing I'm looking
for, just didn't know how to get the syntax correct.

Works fine on VC7.1. I think for VC7.0 you have to define the operator
in-class.

Jonathan
 
M

Makhno

Supplying 'inline' with the definition is perfectly fine and is usually
done when the definition is in the same header but outside the class, mind
you, without 'inline' in such case you are likely to have a multiple
definition error (if you happen to use that header in more than one
translation unit).

I've never had any trouble with multiple definition errors in this case, as
long as I have 'inline' at least once somewhere, and I thought that that was
what the standard implied (my 'strange problem' with VS6 was that I had to
place 'inline' in both places or I got a multiply-defined error).
 
M

Makhno

Works fine on VC7.1. I think for VC7.0 you have to define the operator
in-class.

If I do that, it ignores the cast completely. Thanks for your help, I had
suspected the compiler wasn't up to the job.
 
J

Jonathan Turkanis

Makhno said:
If I do that, it ignores the cast completely. Thanks for your help, I had
suspected the compiler wasn't up to the job.

You mean with VC7.0? I'm not surprised it doesn't work, but I don't
understand what you mean by 'ignores the cast completely'.

Jonathan
 
M

Makhno

You mean with VC7.0? I'm not surprised it doesn't work, but I don't
understand what you mean by 'ignores the cast completely'.

As in 'reacts as though I had never written the cast operator to the Vector
class'.
 
J

Jonathan Turkanis

Makhno said:
As in 'reacts as though I had never written the cast operator to the Vector
class'.

Yes, that's nasty. Did you try using converting constructors instead?

Jonathan
 
J

Jonathan Turkanis

Jonathan Turkanis said:
Yes, that's nasty. Did you try using converting constructors
instead?

You probably need a templated assignment operator too, if you do this.

Jonathan
 
M

Makhno

Did you try using converting constructors instead?

Yes, worked straight away. You're right - perhaps I don't need the cast
operator at all.
You probably need a templated assignment operator too, if you do this.

No, as
Vector<float> pf=pd;
and
Vector<float> pf(pd);
are equivalent;
 
M

Makhno

But that's just one use of the implicit conversion.
How about:

Vector<double> pd;
Vector<float> pf;
// More stuff here.
pf = pd;

?

Hmm, this still seems to work, how peculiar. Vector<> doesn't have an
assignment operator.
 
V

Victor Bazarov

Jonathan Turkanis said:
But that's just one use of the implicit conversion.

How about:

Vector<double> pd;
Vector<float> pf;
// More stuff here.
pf = pd;

?

I didn't suggest a templated assignement operator first because your
example didn't require it. But if you want a general-purpose
substitute for the conversion operator, you need it.

Why? 'pf = pd' expression will result into the use of compiler-
generated assignment operator and a construction of a temporary
on the right side, no? It should be equivalent to

{ Vector<float> temp(pd); pf = temp; }

No special assignment operator is needed here.

Correct me if I am wrong.

V
 
J

Jonathan Turkanis

Makhno said:
Yes, worked straight away. You're right - perhaps I don't need the cast
operator at all.
this.

No, as
Vector<float> pf=pd;
and
Vector<float> pf(pd);
are equivalent;

But that's just one use of the implicit conversion.

How about:

Vector<double> pd;
Vector<float> pf;
// More stuff here.
pf = pd;

?

I didn't suggest a templated assignement operator first because your
example didn't require it. But if you want a general-purpose
substitute for the conversion operator, you need it.

Jonathan
 
V

Victor Bazarov

Makhno said:
Hmm, this still seems to work, how peculiar. Vector<> doesn't have an
assignment operator.

Yes, it does. If you don't declare one yourself, the compiler will
do it for you.
 
J

Jonathan Turkanis

I didn't suggest a templated assignement operator first because your
example didn't require it. But if you want a general-purpose
substitute for the conversion operator, you need it.

I spoke too soon. It's non needed here either. But it's not because
of copy initialization.

Jonathan
 

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
473,774
Messages
2,569,598
Members
45,158
Latest member
Vinay_Kumar Nevatia
Top