Boost logo

Boost :

Subject: Re: [boost] [type_traits] is_base_of<B, D> should work when B is incomplete
From: Andrey Semashev (andrey.semashev_at_[hidden])
Date: 2016-03-04 05:40:17

On 2016-03-04 11:36, Andrzej Krzemienski wrote:
> 2016-03-04 9:24 GMT+01:00 Andrzej Krzemienski <akrzemi1_at_[hidden]>:
>> 2016-03-03 23:33 GMT+01:00 Matt Calabrese <rivorus_at_[hidden]>:
>>> On Thu, Mar 3, 2016 at 5:18 PM, Daniel Frey <d.frey_at_[hidden]> wrote:
>>>>> On 03.03.2016, at 22:57, Andrzej Krzemienski <akrzemi1_at_[hidden]>
>>> wrote:
>>>>> The Standard ([meta.rel]) requires that in std::is_base_of<B, D> D
>>> must
>>>> be
>>>>> a complete type, but it does not require the same of B. This makes
>>> sense,
>>>>> because if we compare a complete type D and an incomplete type B, the
>>>>> former is surely not derived from the latter.
>>>>> In contrast, boost::is_base_of imposes an additional constraint that B
>>>> must
>>>>> also be complete. Could this restriction be lifted?
>>>> That would probably be possible for all modern compilers that have a
>>>> proper std::is_base_of because it requires a compiler intrinsic (unless
>>> you
>>>> can implement it without such an intrinsic and in C++98).
>>> Boost.TypeTraits
>>>> have quite a history and by lifting the restriction, you would drop
>>> support
>>>> for old compilers (think pre-C++11).
>>> Excluding C++98 support, why do you need a compiler intrinsic for this
>>> change? If the reason is the incompleteness check, I've implemented
>>> completeness checking metafunctions before and it's fully possible without
>>> intrinsics in C++11. I described a completeness metafunction that works in
>>> practice a few years ago in a discussion on the mailing list here:
>>> which links to an implementation here: (there
>>> are subtleties to usage, of course). The code that is linked is old and
>>> not
>>> fully correct, although in the time since that thread, I have produced
>>> what
>>> I believe to be a fully correct and well tested implementation.
>> This is quite interesting. However, for my particular purpose, I may not
>> need to employ a C++11 solution.
>> I have an incomplete type boost::in_place_factory. I want to check if a
>> given type T is either derived from boost::in_place_factory. It doesn't
>> have to be very strict: it can get false negative on multiple inheritance;
>> it can give a false positive when T is implicitly convertible to
>> boost::in_place_factory by other means, or simply return false_type when
>> boost::in_place_factory is incomplete.
>> Perhaps there is a C++03-compatible solution to this particular problem?
> Actually, I do not even need a true-false answer; I just need to disable an
> overload (in SFINAE sense) if boost::in_place_factory is either incomplete
> or not a base class of T.

If in_place_factory had a member void tag then you don't even need it
forward declared:

   // in_place_factory.hpp
   class in_place_factory_base
     typedef void _is_in_place_factory;

   // optional.hpp
   template< typename T >
   class optional
     template< typename U >
     optional(U&& in_place,
       typename enable_if_has_type<
         typename U::_is_in_place_factory,
>::type = 0);

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