Boost logo

Boost :

Subject: Re: [boost] Tick: Trait instrospection and concepts library now for C++11
From: Vicente J. Botet Escriba (vicente.botet_at_[hidden])
Date: 2014-06-07 04:28:12

Le 07/06/14 07:18, pfultz2 a écrit :
>> Does your library define just traits or try to emulate Concept Lite?
> I'm not quite sure what you are asking. The library doesn't do everything
> that
> Concepts Lite does. It lets you define concept-like predicates(commonly
> called a
> type trait in C++) in a similiar manner as Concepts Lite does. It does do
> template constraints as well, but this is just done using `enable_if`. Also,
> it
> won't resolve ambiguity between overloads like Concepts Lite does. However,
> I am
> thinking about implementing a mechanism for this. Perhaps something like
> this:
> struct advance1
> {
> template<class Iterator>
> TICK_OVERLOAD_REQUIRES(is_random_access_iterator<Iterator>);
> template<class Iterator>
> void operator()(Iterator& it, int n) const
> {
> it += n;
> }
> };
> struct advance2
> {
> template<class Iterator>
> TICK_OVERLOAD_REQUIRES(is_input_iterator<Iterator>);
> template<class Iterator>
> void operator()(Iterator& it, int n) const
> {
> while (n--) ++it;
> }
> };
> tick::overload<advance1, advance2> advance = {};
> However, this is fairly verbose even with the help of macros. It just might
> be
> easier to add some `not`s to the requires clause.
Have you read the Concept-Based Overloadingin Eric's blog [1]? Eric uses
a dispatching schema on which the Concept definition is the tag dispatcher.

// iterator_concept
template<typename T>
using iterator_concept =
concepts::WeakInputIterator>, T>;
template<typename T>
using iterator_concept_t = meta_apply<iterator_concept, T>;

|// Random-access iterators go here|
|template||<||typename| |RndIt, ||typename| |Diff>|
|void| |advance_impl(RndIt & it, Diff d,|
|||it += d;|
|// All other iterator types go here|
|template||<||typename| |InIt, ||typename| |Diff>|
|void| |advance_impl(InIt & it, Diff d,|
|||for||(; d != 0; --d)|
|template||<||typename| |InIt, ||typename| |Diff,|
|||CONCEPT_REQUIRES(ranges::InputIterator<InIt>() &&|
|void| |advance(InIt it, Diff d)|
|||advance_impl(it, d, ranges::iterator_concept_t<InIt>{});|

This is not perfect, but is the best we can do without concepts
integrated in the language.
What about adding this most_refined trait to your library? it would help
the user to do this tag dispatching?
> Now, non-template members can be disabled, but they need to be made
> templated,
> like this:
> template<class Base>
> struct A : Base
> {
> template<class Self=A, TICK_REQUIRES(is_incrementable<Self>())
> void increment()
> {
> ++(*this);
> }
> };
This is not a good idea. The default will be checked independently of
whether increment is used or not, isn't it?
> However, the library cannot be used with special members(such as copy
> constructors, move constructors, and assignment operators). This is a
> limitation
> of the language, since these special members cannont ever be templates.
I agree that this is a language limitation. The problem is not if they
are templates or not. The problem is when the constraints are checked.

> There
> might be a way to workaround the issue using universal references. I haven't
> really looked into it.
No, this is a real limitation.


Boost list run by bdawes at, gregod at, cpdaniel at, john at