Boost logo

Boost :

Subject: Re: [boost] RFC: type erasure
From: Vicente Botet (vicente.botet_at_[hidden])
Date: 2011-05-25 04:34:26

Steven Watanabe-4 wrote:
> On 05/24/2011 02:07 PM, Vicente Botet wrote:
>> Steven Watanabe-4 wrote:
>>> On 05/23/2011 02:34 PM, Vicente Botet wrote:
>>>> I like how concepts are materialized using a template class that
>>>> implements
>>>> the default behavior of the concept and that can be specialized to map
>>>> type
>>>> to concepts. I understand that you need a second step to introduce the
>>>> functions themselves specializing concept_interface.
>>>> What I don't understand is the overloading issues. Could you use a
>>>> concrete
>>>> example to try to clarify the problems you have addressed?
>>> Okay. Problem 1: Name hiding for member functions.
>>> typedef mpl::vector<
>>> callable&lt;int(int)&gt;,
>>> callable&lt;double(double)&gt;
>>>> test_concept;
>>> If we just use the basic definition of
>>> concept_interface, the second overload
>>> will hide the first since the inheritance
>>> structure looks like:
>>> struct callable1 {
>>> int operator()(int);
>>> };
>>> struct callable2 : callable1 {
>>> double operator()(double);
>>> };
>> I find this normal and expected behavior, so I don't see yet why do you
>> need
>> to avoid this hiding.
> It's normal in the sense that it's what C++
> does by default. I don't see how it can possibly
> be the expected behavior that:
> struct func {
> template<class T>
> T operator()(T t) { return t; }
> };
> typedef mpl::vector<
> callable&lt;int(int)&gt;,
> callable&lt;double(double)&gt;
>> test_concept;
> func f1;
> any<test_concept> f(f1);
> f(1); // calls func::operator()<double>??
> From the point of view of someone trying to
> use the library, the two instances of callable
> are equal. Having one hide the other is surprising.

 I understand it now. It seems that I have forgotten this case on
Many many thanks.

>>> For free functions, I had a problem akin to name
>>> hiding when I defined a single namespace scope
>>> overload with concept_interface arguments. Using
>>> an inline friend function that takes the derived
>>> type works with some care to avoid duplicate
>>> definitions.
>> I'm sorry but I don't reach to see what is the real problem. I guess it
>> is
>> because I don't see the need of introducing the using sentence. Please
>> could
>> you present a real concrete case of overloading free functions that needs
>> two different specializations of concept interface?
> Consider operator+. Either the first argument
> or the second argument or both may be a
> type_erasure::any. I need two specializations,
> because there are two arguments. To use
> friend function defined inline I have to
> inject operator+ into exactly one of the
> arguments.

I don't see if I understood it now. I suspect that you mean that either the
first argument
or the second argument or both may be a placeholder, isn't it?

I originally tried to handle free functions with
namespace scope overloads like this:


Unfortunately, this failed with the example
print_sequence.cpp, because of
ostreamable<_os, const char*>, ostreamable<_os, _t>
Only one of these was being considered
for overload resolution.

>>> You can check the tests for details on what I expect
>>> to work. Most of the tests for specific concepts
>>> have a test_overload test case.
> I've read some of them. I guess I understand what you expect to work, but
> I
> don't see why you need to specialize twice the concept_interface class for
> the same concept.

I couldn't get all the tests to pass with any other
solution I tried. If you have a simpler way to
specialize concept_interface for ostreamable or
callable that passes all my tests I'd love to
hear about it, but I've tried and this is the
best I could come up with.

I'm just trying to understand what kind of problems you have addressed to
see if I can have the same in Boost.Opaque.

To summarize the reasons for multiple specializations:
- For member functions, the second and subsequent instances
  of a concept need to be treated differently from
  the first, because they need an extra using declaration
  (which would be ill-formed in the first occurrence).
- For non-member functions, one specialization is needed
  for each argument that can be a type_erasure::any to
  make sure that the function gets added to the overload
  set regardless of what subset of the arguments is erased.

Thanks again for the clearer explanations.


View this message in context:
Sent from the Boost - Dev mailing list archive at

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