« Return to Thread: Overloading on concepts

Re: Overloading on concepts

by Johan Torp :: Rate this Message:

Reply to Author | View in Thread

Terje Slettebø wrote:
Regarding what you can and can't detect with traits: Things you can detect:

- Static and non-static member functions, member constants, member types and
member class templates.
- Much of the operators.
- All the stuff that Boost Type Traits gives you can be used.

Things you can't detect (without specialising the traits for the types in
question):

- Constructors and destructors (they don't have a name, so can't be detected
using traits detecting member functions)
- Operators that has to be class members, such as assignment operator,
member access operator, subscript operator and function call operator. It
seems like a rather arbitrary restriction to me that these have to be member
functions, and it greatly reduces the ability to perform concept checks
where they are involved.
- Since name lookup is performed before access check, you may get a
compile-time error, rather than SFINAE, if a type has a required member, but
where the member is inaccessible (private or protected).
Great post, exactly what I want to know - thanks.

Terje Slettebø wrote:
Also, concept checking using enable_if is an all-or-nothing affair (either
it matches or it doesn't), so if you want to implement concept overloading
based on best match (for example with regard to the iterator concepts), you
have to perform the ordering, yourself. There's an included example
demonstrating this (in the original version of the library, this is located
in libs/concept_traits/example/std_advance.cpp).
Well, you could implement "get_iterator_tag" using enable_if + your concept traits and then use regular function overload dispatch. Since boost tags inherit from each other according to their respective refinement, the function overloading would select the most refined concept. This could be implemented once and or all and supplied with the concept traits library.

<code>
template<class Iterator> void advance_impl(Iterator it, int n, boost::random_access_traversal_tag);
template<class Iterator> void advance_impl(Iterator it, int n, boost::single_pass_traversal_tag);

template<class Iterator> void advance(Iterator it, int n) {
  advance_impl(it, n, get_iterator_tag(it));
}
</code>


Best Regards, Johan

 « Return to Thread: Overloading on concepts