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 SFINAE-friendly 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 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 class W> concept Functor { template
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
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