
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