Boost logo

Boost :

Subject: Re: [boost] [type_traits] A partial implementation of boost::is_constructible
From: Paul Fultz II (pfultz2_at_[hidden])
Date: 2016-02-19 13:03:18

On Friday, February 19, 2016 at 1:47:05 AM UTC-6, Andrzej Krzemienski wrote:
> I filed a ticket about a potential improvement of type trait
> boost::is_constructible:
> I am solving the following problem. I have a one-argument perfect
> forwarding explicit constructor and want to constrain it only to the cases
> when T is constructible from U:
> ```
> template <typename T>
> struct optional
> {
> template <typename U>
> explicit optional(U&& v, ENABLE_IF(is_constructible<T, U&&>))
> {...}
> };
> ```
> I cannot afford to use the "fallback" implementation of
> boost::is_constructible (the one that forwards to is_convertible) because
> I
> would be constraint my constructor too much: I would rather leave it
> under-constrained.
> I do not need the full implementation of is_constructible (that would need
> variadic templates) because I am only using the two-argument version (and
> I
> suppose my problem is not isolated).
> I would like a partial implementation of is_constructible that works
> correctly for two arguments only; and a macro that allows me to test if it
> is available.

To implement this properly requires a compiler with expression SFINAE, which
is supported in clang, gcc 4.4 or higher, and partially supported in MSVC
2015. Both MSVC and clang do provide a `__is_constructible` type trait
intrinsic. I am not sure what version of MSVC this was introduced.

Utimately, if you are wanting Boost.Optional to have compatabiliy with
compiler versions then it will need to fallback on `is_convertible`. For
case, `is_constructible` could be implemented something like this:

template<int N>
struct holder
{ typedef void type; };

template<class T>
T declval();

template<class T, class U, class=void>
struct is_constructible
: false_type

template<class T, class U>
struct is_constructible<T, U, typename holder<
: true_type


template<class T, class U>
struct is_constructible
: integral_constant<bool, (__is_constructible(T))>


template<class T, class U>
struct is_constructible
: is_convertible<U, T>


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