
Boost : 
Subject: Re: [boost] [Tick] Universal quantified concepts/traits
From: Vicente J. Botet Escriba (vicente.botet_at_[hidden])
Date: 20150106 15:20:33
Le 06/01/15 19:48, pfultz2 a écrit :
>> No, this trait has two parameters F and Wt. I'm looking for a trait with
>> a single parameter W, the type constructor.
> Ok I see, you mean that W is a templates.
Not necessarily. W can be a class that has a nested template class apply
with one parameter. That is a type constructor.
>
>> This SO question presents the same context.
> Well that is one limitation. However, template members could be solved
> either
> by SFINAEfriendly lift operator or with reflection. However, what you are
> trying to achieve is very difficult in C++ mainly due to template
> specialization, function overloading, and substitution failure. Say we had a
> simple function foo:
>
> template<class T>
> U foo(T);
>
> Now, `foo` takes a T and returns U some other type. This is simple for the
> compiler to follow, however, `foo` could return a type from a metafunction
> like this:
>
> template<class T>
> typename some_metafunction<T>::type foo(T);
>
> So with this, the compiler now has to trace each and every type `T`. Now
> even
> if thats possible, it doesn't even completely solve the problem. Next thing
> is
> the `w` template could have a constraint that only works for integrals:
>
> template<class T, class=std::enable_if_c<(std::is_integral<T>())>>
> class w;
>
> So now if `foo` takes an `int` and returns `int`, but also takes a `long`
> and
> returns `std::vector<int>` then we have a problem. The map function could
> work
> correctly and map `w<T>` to `w<U>` however trying to map `w<long>` would be
> a
> compile error. So should this be considered a functor or not? Trying to
> decide
> whether its a functor in the general sense is difficult and its much better
> to
> decide on actual concrete or dependent types.
>
> Of course, it is really useful to check your code in the more general sense
> instead of relying on concrete type, so concepts can actually help solve
> this
> problem(the C++0x concepts, not the SFINAE concepts being currently
> proposed).
> So you could possibly write something like this:
>
> template<template<class...> class W>
> concept Functor
> {
> template<class F, class T, class
> U=decltype(std::declval<F>()(std::decval<T>()))>
> W<U> fmap(F f, W<T> w);
> };
>
> So the concept will ensure you are following the correct "interface", so if
> you have a function that will use a `Functor` like this:
>
> template<Functor W, class T, class F>
> void apply(W<T> x, F f)
> {
> fmap(f, x);
> }
>
> So the compiler will check that you are using a `Functor` in the template.
> It
> doesn't need to check every type(like when using SFINAE concepts). Then at
> instantiation time the compiler will check that the concrete types meet the
> requirements of the concept `Functor`.
>
>
This is exactly what I would like to be able to do :) You have resumed
quite well the need and the solution using C++0x Concepts.
Unfortunately Concept Lite doesn't allows to express this kind of
concepts :(
Best,
Vicente
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk