From: Matthias Pospiech on
I have a Class for complex operations:

class CComplex
{
public:
inline CComplex() { re=im=0.0; }
inline CComplex operator*(CComplex c) { return
CComplex(re*c.re-im*c.im,re*c.im+im*c.re);}
inline CComplex operator*(double &d) { return CComplex(re*d,im*d);}
double re,im;
};

However when multiplying double * CComplex the operation fails

double m_Phase[8192][8192]; // Phase of Field
double m_Amplitude[8192][8192]; // Amplitude of Field
CComplex m_Field[8192][8192]; // Full electric Field


m_Field[x][y]= (m_Amplitude[x][y]) * (Expi(m_Phase[x][y]));


with

error C2677: Bin�rer Operator '*': Es konnte kein globaler Operator
gefunden werden, der den Typ 'CComplex' akzeptiert (oder keine geeignete
Konvertierung m�glich)

(no Operator found that accepts CComplex)

What is going wrong ??

Matthias
From: Ulrich Eckhardt on
Matthias Pospiech wrote:
> class CComplex
> {
> public:
> inline CComplex()
> { re=im=0.0; }
> inline CComplex operator*(CComplex c)
> { return CComplex(re*c.re-im*c.im,re*c.im+im*c.re); }
> inline CComplex operator*(double &d)
> { return CComplex(re*d,im*d);}
> double re,im;
> };

Several things:
1. Const correctness
One of the overloads takes a reference to a double, in what way does it
modify that value? I guess none, but your function signature implicitly
says something else and it affects the ability to call this function with
a temporary. The same with the left side of the operator*, your function
signatures say that you are modifying it, so you can't use it on constants
or temporaries.
2. Symmetry
If the double was on the left hand side, none of the overloads would fit.
You could only create a free function style overload:

CComplex operator*( double, CComplex );

However, then you could just as well move all overloads to the surrounding
namespace, i.e. not make them members of class CComplex.
3. Reinventing the wheel
There already is a complex type provided by the C++ standard. It even is a
template for use with float, double or long double and provides many
functions and operators.

> However when multiplying double * CComplex the operation fails

The 'this' object is always on the left side of the operator, so you can't
create one that takes a double there unless you make it a free function.

Uli

--
FAQ: http://ma.rtij.nl/acllc-c++.FAQ.html
From: Bart van Ingen Schenau on
Matthias Pospiech wrote:

> I have a Class for complex operations:
>
> class CComplex
> {
> public:
> inline CComplex() { re=im=0.0; }
> inline CComplex operator*(CComplex c) { return
> CComplex(re*c.re-im*c.im,re*c.im+im*c.re);}
> inline CComplex operator*(double &d) { return
> CComplex(re*d,im*d);}

These overloads of operator* both assume a left-hand-side of type
CComplex.
Therefor, your class only supports multiplications of the forms
CComplex * CComplex
CComplex * double

> double re,im;
> };
>
> However when multiplying double * CComplex the operation fails

To support this operation, you need a non-member oberload of operator*
for the combination (double, CComplex)
CComplex operator*(double lhs, const CComplex& rhs);

If the operator is commutative (swapping the operands does not affect
the result), you can implement this overload as
CComplex operator*(double lhs, const CComplex& rhs)
{
return rhs * lhs;
}

>
> Matthias

Bart v Ingen Schenau
--
a.c.l.l.c-c++ FAQ: http://www.comeaucomputing.com/learn/faq
c.l.c FAQ: http://www.eskimo.com/~scs/C-faq/top.html
c.l.c++ FAQ: http://www.parashift.com/c++-faq-lite/
From: Matthias Pospiech on
Ulrich Eckhardt schrieb:
> Matthias Pospiech wrote:
>> class CComplex
>> {
>> public:
>> inline CComplex()
>> { re=im=0.0; }
>> inline CComplex operator*(CComplex c)
>> { return CComplex(re*c.re-im*c.im,re*c.im+im*c.re); }
>> inline CComplex operator*(double &d)
>> { return CComplex(re*d,im*d);}
>> double re,im;
>> };
>
> Several things:
> 1. Const correctness
> One of the overloads takes a reference to a double, in what way does it
> modify that value? I guess none, but your function signature implicitly
> says something else and it affects the ability to call this function with
> a temporary.
Oh that has not much to say. I have this CComplex class written by
somebody else and thought using references would be faster.

> The same with the left side of the operator*, your function
> signatures say that you are modifying it, so you can't use it on constants
> or temporaries.
How am I modifing what ? I think i do not understand your comment.


> 2. Symmetry
> If the double was on the left hand side, none of the overloads would fit.
> You could only create a free function style overload:
>
> CComplex operator*( double, CComplex );

Where can I find more information about 'free function style overload'.
I am not a C++ expert and have never heard of that.

>
> However, then you could just as well move all overloads to the surrounding
> namespace, i.e. not make them members of class CComplex.
Off course I can do that. But what would change then ?

> 3. Reinventing the wheel
> There already is a complex type provided by the C++ standard. It even is a
> template for use with float, double or long double and provides many
> functions and operators.

I simply did not know. And the problem is, that all C++ project here use
the other class.

>> However when multiplying double * CComplex the operation fails
>
> The 'this' object is always on the left side of the operator, so you can't
> create one that takes a double there unless you make it a free function.
I understand the problem, but need more information about free functions.

Matthias
From: Matthias Pospiech on
Bart van Ingen Schenau schrieb:
>
> To support this operation, you need a non-member oberload of operator*
> for the combination (double, CComplex)
> CComplex operator*(double lhs, const CComplex& rhs);
>
> If the operator is commutative (swapping the operands does not affect
> the result), you can implement this overload as
> CComplex operator*(double lhs, const CComplex& rhs)
> {
> return rhs * lhs;
> }
>
I think I understand the idea, but it fails:

error C2678: Bin�rer Operator '*': Es konnte kein Operator gefunden
werden, der einen linksseitigen Operanden vom Typ 'const CComplex'
akzeptiert (oder keine geeignete Konvertierung m�glich)
1>
[...].h(119): kann 'CComplex operator *(double,const CComplex &)' sein
1>
[...].h(95): oder "CComplex CComplex::operator *(CComplex)"
1>
[...].h(101): oder "CComplex CComplex::operator *(double)"
1> bei Anpassung der Argumentliste '(const CComplex, double)'

Matthias