AMDG On 03/09/2015 06:36 PM, Matt Calabrese wrote:
On Mon, Mar 9, 2015 at 4:29 PM, Steven Watanabe
wrote: 1) You don't pay for what you don't use. Putting the registration in the constructor means that it will always happen whether it's needed or not. 2) It still won't catch everything. In the example I posted, the object is captured by an any type which does not support callable, and later cast to another any type which does. The constructor will therefore not instantiate callable
. I think that explicit manual registration is less likely to to cause hard to find bugs that automatic registration that only works most of the time. Okay, this facility is much different from what I thought it was. I should have looked at the example code more closely before replying. I read the description and thought it was for the following type of situation:
////////// void foo() {} function_any
fun_foo = &foo; // Start by type-erasing via a callable concept // Convert to a less-refined concept plain_any any_foo = fun_foo; // target type is still void(*)(), no additional indirection
// Get the object back as a function_any
dynamic_any_cast >(any_foo); // should succeed ////////// In other words, I assumed it only worked if the type were originally erased via the more-refined concept before being converted to the less-refined any. In this case I imagine you would be able to keep track of the information by way of the original conversion.
From an implementation stand-point, just casting
to the original captured type is pretty easy to
support. The problem is that if I support that,
then several other kinds of casts should be possible
as well.
If we have an any, we should be able to do
an upcast followed by a downcast, regardless
of where the any came from. Thus, the following
sequence should work:
- capture as RandomAccessIterator
- cast to BidirectionalIterator
- cast to ForwardIterator
- dynamic_any_cast back to BidirectionalIterator
The cast sequence RandomAccessIterator -> BidirectionalIterator ->
ForwardIterator should be exactly equivalent to
RandomAccessIterator -> ForwardIterator. Therefore,
the following should also work:
- capture as RandomAccessIterator
- cast to ForwardIterator
- dynamic_any_cast to BidirectionalIterator
The simplest rule to make sure that such conversions
always work is to say that if an object was originally
captured as ConceptA, then a dynamic_any_cast from
ConceptB to ConceptC will work if ConceptA is more refined
than ConceptC.
So far it's all pretty straightforward. Now we come to
the annoying part. I think that every any which holds the
same value should be equivalent. In other words, if I have
any<...> a1, a2; and typeid_of(a1) == typeid_of(a2), then
dynamic_any_cast