Boost logo

Boost :

Subject: Re: [boost] iterator_category> algorithm selection with cast operator
From: Jeffrey Lee Hellrung, Jr. (jhellrung_at_[hidden])
Date: 2010-06-25 13:26:01


On 6/25/2010 8:11 AM, gzp wrote:
>
> Hello,
[...]
> Using the iterator_category concept empty structs are used to check, select
> functions at compile time.
> struct A {};
> struct B : A {}
> void foo( A ) { alg1... }
> void foo( B ) { alg2... specialized for B }
> template<typename T> void foofoo( T ){ foo( getCategory<T>() ); }
>
> My first idea was to use multiple inheritance, but it result error
> (ambiguous call)
> struct A {};
> struct B : A {};
> struct A2 : A {};
> struct B2 : A2, B {};
>
> void foo( A ) { alg1... }
> void foo( B ) { alg2... specialized for B }
> void foo( A2 ) { alg3... specialized for A2 }
> void g() { B2 b; f(b); } // error: is it f(B) or f(A2)
>
> Than I've used cast operators and inheritance stating that, a B2 is mainly
> an A2 and secondly a B:
> struct A {};
> struct B : A {};
> struct A2 : A {};
> struct B2 : A2 { operator B() { return B(); } };
>
> void foo( A ) { alg1... }
> void foo( B ) { alg2... specialized for B }
> void foo( A2 ) { alg3... specialized for A2 }
> void g() { B2 b; f(b); } // shall call f(A2)
>
> So my question is that, is it a working method, or the whole concept is
> wrong ?
> Has anyone used something similar ? If so, is there some sample
> codes/results?

The nice thing about using inheritance (which necessarily restricts your
concept hierarchies to be linear) is that your conversions are
automatically transitively closed. Conversions don't have this feature,
i.e., if A -> B and B -> C via conversion operators, then it won't
(necessarily) be the case that A -> C (where "->" means "is convertible
to"); you'd have to add that conversion explicitly. This would affect
tag dispatching, e.g.,

dispatch(boost::single_pass_traversal_tag);
dispatch(boost::random_access_traversal_tag);

f(Iterator it) { dispatch(boost::iterator_traversal< Iterator >::type()); }

only works reliably because boost::bidirectional_traversal_tag ->
boost::single_pass_traversal_tag, even though
boost::bidirectional_traversal_tag only (directly) inherits from
boost::forward_traversal_tag.

Other than the above issues with transitive conversions, however, I
believe using conversion operators suffice.

- Jeff


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