Boost logo

Boost :

From: brianjparker (brianjparker_at_[hidden])
Date: 2002-02-21 19:07:48


One limitation of the existing C++ language that I have found to be a
problem when implementing a valarray-like array class is the fact
that if a function formal argument involves *any* template parameter
then implicit conversions are disabled for that argument when calling
the function, even in cases where there is sufficient type
information to do the conversion- in particular for function formal
arguments of the form C<T>.

This is very non-intuitive, and can lead to suprising results for the
user depending upon the implementation choices in the library e.g.
the std::complex library behaves differently (and less intuitively)
by requiring explicit casts if it is implemented with fully generic
template functions rather than providing specialisations for
complex<float>, complex<double> etc.

Another example-

A generic function that works for a valarray of any type is written as
follows-

template<typename T>
void func(const std::valarray<T>& V)
{
 ...
}

But this function unexpectedly fails to compile in the following call
as the proxy object (slice_array) does not have its conversion
operator called to convert to a valarray<double>.

std::valarray<double> V(100);

func(V[std::slice(1, 4, 1)]); // compile error

The caller needs, surprisingly, to do an explicit cast

func(static_cast<std::valarray<double> >(V[std::slice(1, 4,
1)])); // OK

This is a particular problem for proxy classes as they are designed
to be transparent to the user and so the reason for the compile-time
error may not be obvious.

Proposed Solution:
The solution is simply to require that for a templated function
parameter of the form C<T>, if type deduction fails then if an
(unambiguous) conversion exists to a C<T> then the conversion is
performed.
However, this additional test is done *only* if no other matching
overload (template or non-template) is found. This restriction is
needed to ensure full backwards compatibility as it therefore applies
only in cases that would otherwise not compile.

(Note that a similar conversion is already provided for by the
standard- a derived class D<T> can be converted to a base class C<T>
if no other deduction can be done).

Proposed change to wording of standard:
14.8.2.1 [temp.deduct.call]

Add something like the following clause at the obvious place-

"If no other overload matches and if P is a class, and P has the form
template-id, then A can be a type unambiguously convertible to the
deduced A. "

,Brian Parker


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