Arithmetic conversions/promotion and templates



 DEVELOP > c-Plus-Plus > Arithmetic conversions/promotion and templates

LINK TO THIS PAGE  


rating :  0   |  0


  Page 1 of 1

1

 
Topic: DEVELOP > c-Plus-Plus
User: "=?ISO-8859-1?Q?Christian_Brechb=FChler?="
Date: 19 Oct 2003 11:44:16 AM
Object: Arithmetic conversions/promotion and templates
Let me use complex numbers as a familiar example. The following is
taken verbatim from Bjarne Stroustrup, "The C++ Programming Language",
except the include line and the "no match" comments. It won't compile.
#include <complex>
// section 22.5:
// Throughout this book, I have used complex as a class rather than as a
// template. This is feasible because I assumed a bit of namespace magic to
// get the complex of double that I usually prefer:
typedef std::complex<double> complex;
// section 11.3:
// For example, from looking at a math textbook we would expect this to
work:
void f()
{
complex a = complex(1,2);
complex b = 3;
complex c = a+2.3;
complex d = 2+b; // no match for `int + complex&' operator
complex e = -b-c;
b = c*2*c; // no match for `complex& * int' operator
}
(Obviously we could kludge it by replacing 2 by 2.0 or double(2) etc.,
but I think we rightfully expect it to work exactly as Stroustrup wrote it.)
Questions: What was the rationale for implementing the standard library
like this?
Is there a generic way to accept any type that the usual arithmetic
conversions (C.6.3) can promote to double as the left or right argument
to a binary operator?
(I tried templating on the "simple" type, but when I do it for the left
and right argument, a+b becomes ambiguous. -- I there a way to express
that a template parameter "class T" must have a conversion to double?)
Thanks
Christian
.

User: "Victor Bazarov"

Title: Re: Arithmetic conversions/promotion and templates 19 Oct 2003 12:26:38 PM
"Christian Brechbühler" <c_brechbuehler@yhaoo.com> wrote...

Let me use complex numbers as a familiar example. The following is
taken verbatim from Bjarne Stroustrup, "The C++ Programming Language",
except the include line and the "no match" comments. It won't compile.



#include <complex>

// section 22.5:
// Throughout this book, I have used complex as a class rather than as a
// template. This is feasible because I assumed a bit of namespace magic

to

// get the complex of double that I usually prefer:
typedef std::complex<double> complex;

// section 11.3:
// For example, from looking at a math textbook we would expect this to
work:
void f()
{
complex a = complex(1,2);
complex b = 3;
complex c = a+2.3;
complex d = 2+b; // no match for `int + complex&' operator
complex e = -b-c;
b = c*2*c; // no match for `complex& * int' operator
}



(Obviously we could kludge it by replacing 2 by 2.0 or double(2) etc.,
but I think we rightfully expect it to work exactly as Stroustrup wrote

it.)


Questions: What was the rationale for implementing the standard library
like this?

This is a question for comp.std.c++. They discuss the "why" questions.
We here discuss the "how".

Is there a generic way to accept any type that the usual arithmetic
conversions (C.6.3) can promote to double as the left or right argument
to a binary operator?

Yes.
#include <complex>
typedef std::complex<double> complex;
template<class T>
complex operator +(const complex& c, T t) {
return std::operator +(c,complex(t)); // call the std:: one
}
void foo() {
complex a(1,2);
complex b = 2 + a; // ours works fine
}


(I tried templating on the "simple" type, but when I do it for the left
and right argument, a+b becomes ambiguous. -- I there a way to express
that a template parameter "class T" must have a conversion to double?)

I am not sure what you're saying here. Please supply the code.
Victor
.
User: "=?ISO-8859-1?Q?Christian_Brechb=FChler?="

Title: Re: Arithmetic conversions/promotion and templates 19 Oct 2003 11:00:56 PM
Victor Bazarov wrote:

"Christian Brechbühler" <c_brechbuehler@yhaoo.com> wrote...

Is there a generic way to accept any type that the usual arithmetic
conversions (C.6.3) can promote to double as the left or right argument
to a binary operator?



Yes.

#include <complex>

typedef std::complex<double> complex;

template<class T>
complex operator +(const complex& c, T t) {
return std::operator +(c,complex(t)); // call the std:: one
}

void foo() {
complex a(1,2);
complex b = 2 + a; // ours works fine
}

Cool, thanks! I see it works, but how? With T=int, your definition
explicitly defines the operator complex + int. But apparently at the
same time it defines int + complex!
Your definition supports 2 + a and a + 2. Why?
I had tried something that looks superficially the same, except it
doesn't use typedef:
#include <complex>
template<class T, class Real>
std::complex<Real> operator +(const std::complex<Real>& c, T t) {
return std::operator +(c,std::complex<Real>(t));
}
void foo() {
std::complex<double> a(1,2);
std::complex<double> b = 2 + a; // error: no match
std::complex<double> c = a + 2;
}
And here only one of the operators gets defined.
Thanks again to Victor for the quick and neat answer!
Christian
.


User: "Gianni Mariani"

Title: Re: Arithmetic conversions/promotion and templates 19 Oct 2003 12:59:52 PM
Christian Brechbühler wrote:

Questions: What was the rationale for implementing the standard library
like this?

I don't know.

Is there a generic way to accept any type that the usual arithmetic
conversions (C.6.3) can promote to double as the left or right argument
to a binary operator?

(I tried templating on the "simple" type, but when I do it for the left
and right argument, a+b becomes ambiguous. -- I there a way to express
that a template parameter "class T" must have a conversion to double?)

I think you may need to be more generic with your example because
you can supply your own operators that solves the complex problem.
template <typename T>
inline complex<T> operator+ (
const typename complex<T>::value_type & r,
const complex<T> & c
)
{
return complex<T>( r, 0 ) + c;
}
template <typename T>
inline complex<T> operator* (
const complex<T> & c,
const typename complex<T>::value_type & r
)
{
return c * complex<T>( r, 0 );
}
.


  Page 1 of 1

1

 


Related Articles
 

NEWER

pg.1232     pg.940     pg.716     pg.544     pg.412     pg.311     pg.234     pg.175     pg.130     pg.96     pg.70     pg.50     pg.35     pg.24     pg.16     pg.10     pg.6     pg.3     pg.1

OLDER