4

I have

auto result = std::is_convertible
    < boost::optional<int>
    , bool
    >::value;

static_assert( result , "task should return bool" );

and it fails to compile. The definition of std::is_convertible is

template< class From, class To > struct is_convertible;

and optional is clearly convertible to boolean because we always use it like

void(boost::optional<int> const & value){
    if(value){
        std::cerr << *value << endl; 
    }
}

what am I missing here?

bradgonesurfing
  • 30,949
  • 17
  • 114
  • 217

1 Answers1

10

boost::optional's operator bool is explicit. It works inside an if's condition, because it is a contextual conversion.

You need std::is_constructible, which tries to perform an explicit conversion.

The following compiles

static_assert
    ( std::is_constructible<bool, boost::optional<int>>::value
    , "msg" );

and the following fails to compile because optional is not convertible to int

static_assert
    ( std::is_constructible<int, boost::optional<int>>::value
    , "msg" );
bradgonesurfing
  • 30,949
  • 17
  • 114
  • 217
Quentin
  • 62,093
  • 7
  • 131
  • 191
  • Could you please elaborate on how to use std::is_constructible to detect if I can convert the type to bool? I'm not sure how to go about it. – bradgonesurfing Nov 15 '18 at 12:25
  • @bradgonesurfing There's a gotcha in that the arguments are reversed compared to `std::is_convertible`, but it should be as simple as `std::is_constructible>`. – Quentin Nov 15 '18 at 12:26
  • 1
    Thanks @quentin I added the examples to the answer so it's clear to the next person coming this way :) – bradgonesurfing Nov 15 '18 at 12:32