Boost logo

Boost :

From: Eric Ford (eford_at_[hidden])
Date: 2001-09-28 01:25:59


> I'm not sure if it is a good idea to leave the default
implementations
> empty.
>
> If I want to use a given UDNT (user defined number type), then the
first
> thing I have to do is to specialize all those traits and functions
for which
> I can give a meaningful specialization.
> Now, suppose that my BigFloat doesn't support, say, 'cos()'; but I
need to
> use it in some algorithm and I get the compiler error that cos()
isn't
> specialized for BigFloat.
> I have two choices: forget about using BigFloat or write myself (the
> BigFloat user, not the BigFloat implementer) the specialization.
> However, I think that chances are that most of the times I will end
up
> writting my own specialization, becuase it is unlikely that I can
forget
> about BigFloat for this job (or I wouldn't have chosen it in the
fist place)

I'm not sure I fully understand your example. If your algorithm
doesn't use cos, then since cos is a template, the compiler will never
invoke cos<BigFloat> and you won't get an error. If you do write code
that calls cos<BigFloat> then you will get an error. If you'd like to
have use it just that once then you could do something liek
cos<double>(numeric_cast<double>(x)), where x is a BigFloat. If you
want to call it often, then you'd probably want to specialize cos for
your BigFloat type. I'd be worried that users would expect
cos<BigFloat> to provide an accuracey consistant with the precision of
BigFloat. If the default implementation casts it to a double, then
users could easily be misled. If they have to either cast or
specialize themselves, then I'd think it's less likely someone would
get intro trouble. I suppose we could provide a macro to make
specializing a "standard function" for a user defined type a one
liner, provided they were willing for it to be implemented in terms of
casting their type to a double, doing the calculation in double, and
casting the answer back to their type.

> Second:
> ~~~~~~
>
> I think that the functions should take "T const&" instead of "T
const".
> For a built-in type, pass by value is OK, but this is targeted to
arbitrary
> types, not just built ins.

What about using call_traits<T>::param_type?

> Third:
> ~~~~
>
> In:
>
> template<> TYPE FUNC< TYPE >(const TYPE x) \
> { return boost::numeric_cast<TYPE>(::std::STDFUNC(x)); };
>
> The numeric_cast<> here is unnecesary.
> STDFUNC is passed to the macro such that it has the signature TYPE
> (*f)(TYPE);
> If it didn't, then another conversion would be required from TYPE to
the
> function argument.

I had in mind allowing for implicit use of more accurate type to
perform a calculation. (e.g. if pow didn't have a float
implementation, then it could convert the float to a double, perform
the calculation in double, and cast back to float). In retrospect,
there's probably no instance where this is actually necessary. So the
numeric_cast can probably be removed.

> Everything else seems good to me.

Thanks for looking it over.


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk