Boost logo

Boost :

From: Howard Hinnant (hinnant_at_[hidden])
Date: 2002-01-20 13:15:02


> --- In boost_at_y..., "Ralf W. Grosse-Kunstleve" <rwgk_at_y...> wrote:
>> (This question is related to my previous posting.)
>>
>> Here is something I am often wondering about:
>>
>> template <typename NumVectorType>
>> NumVectorType operator*(const NumVectorType& lhs, const
> NumVectorType& rhs);
>>
>> Is there a way to classify or register types as NumVectorTypes?
>>
>> I know how to make a distinction between types once I am
>> /inside/ the function (using traits). However, what I am
>> after is something like:
>>
>> tell_compiler {
>> possible typename NumType:
>> double
>> float
>> etc.
>> possible typename NumVectorType:
>> std::vector<NumType>
>> boost::array<NumType, *>
>> etc.
>> }
>>
>> Then the compiler should select template functions only if the
>> concrete type is registered under the typename label.
>>
>> Is this asking for a formalization of "concepts?"
>> To which degree can this be emulated with the language as-is?
>> What can we expect in the future (from the standard committee)?
>>
>> Thanks,
>> Ralf
>
> On Sunday, January 20, 2002, at 12:22 PM, rogeeff wrote:
>
> I was thinking in this direction some time ago. The closest thing I
> found is to define partial specialization by type list. But I did not
> find a way to define automatically all specialization by given
> typelist T and template definition foo<t>. For example,
> if T = int, fload, double
>
> then I want to write foo<T> and compiler should understand it like
> foo<int>
> foo<float>
> foo<double>
>
> Does anybode know the MP solution (if there is one)?
>
> Gennadiy.

I too have needed this concept. I've seen it discussed before under
subjects of "constrained genericity", and "restricted templates". I
have never come up with a satisfactory implementation within the current
language.

Specifying what types you want the template to be constrained to could
be done with a traits class. For example, here's an imaginary syntax
using a "restrict" keyword:

template <typename NumType :
restrict(boost::is_arithmetic<NumType>::value)>
NumType
foo(NumType t) {...}

People often say: Well if NumType doesn't satisfy the requirements of
foo, then you will get a compile time error. So what is the problem
with that?

As a library writer I would like to be able to create a restricted
template foo that would accept only (for example) arithmetic types. But
if client code creates a function foo that takes a user-defined type, I
want it to behave as if there is no template foo, even if he has brought
it into scope.

Problem case:

// Library code

namespace Lib {

template <class NumType>
NumType
foo(NumType x);

} // Lib

// client code

using namespace Lib;

struct A {};

struct B
{
        B(A);
};

B foo(B);

void bar()
{
        A a;
        foo(a);
}

Without the library template foo, the client code works. The "a"
implicitly converts to a B and calls the user's foo(B) as intended. But
if the templated foo is introduced into the scope, then foo(a) resolves
to the library's templated foo instead of to the user's foo(B) - whether
or not foo<A> will compile. So the introduction of the templated foo
can either cause a compile time error in code that previously worked.
Or worse, it could silently change the behavior of a correctly running
program. Thus the need to tell the compiler to not consider the
templated foo except for the types it is restricted to.

-Howard


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