Opened 6 years ago

Last modified 6 years ago

#6974 new Bugs

boost::optional compilation error with boost::function and boost::fusion::vector

Reported by: Jonathan Jones <jonathan.jones@…> Owned by: Fernando Cacciola
Milestone: To Be Determined Component: optional
Version: Boost 1.49.0 Severity: Problem
Keywords: Cc:

Description

If you compile the following on g++ 4.4.5, it will fail to compile because the optional_base copy constructor and destructor are protected.

boost::optional< boost::fusion::vector1<boost::function0<void> > >

A duplication program is attached.

Attachments (1)

optional.cpp (339 bytes) - added by Jonathan Jones <jonathan.jones@…> 6 years ago.

Download all attachments as: .zip

Change History (5)

Changed 6 years ago by Jonathan Jones <jonathan.jones@…>

Attachment: optional.cpp added

comment:1 Changed 6 years ago by Steven Watanabe

Well that's annoying. optional_base is an implementation detail, but it looks like it's escaping while resolving overload resolution for the copy constructor of optional_base, because of the enable_if in the (converting) constructor of fusion::vector1.

comment:2 Changed 6 years ago by Steven Watanabe

This particular bug appears to be fixed in gcc 4.7.

comment:3 Changed 6 years ago by Steven Watanabe

I'm not quite sure where the best place to fix this is.

  • is_convertible should never fail, but it's probably not feasible to fix it.
  • fusion::vector1 shouldn't cause overload resolution to fail, but I don't see any way to avoid this problem, given the limitations of is_convertible.
  • I could create a special case for is_convertible for boost::function, but it would be wrong in some edge cases that a compiler intrinsic (or perhaps a C++11 implementation) would be able to get right.
  • That leaves making the copy constructor of optional_base public. This ignores the underlying problem that external code is making assumptions about what it can do with an arbitrary type. I really hate to hack the code like this when it isn't the source of the problem.
  • And of course the final option is to modify the constructors so that optional_base is never passed to a function that requires overload resolution against T. This one is out because it's too messy.

comment:4 Changed 6 years ago by Jonathan Jones <jonathan.jones@…>

For what it's worth, the local workaround we deployed was to makes the optional_base copy constructor and destructor public, but _only_ when the BOOST_IS_CONVERTIBLE macro isn't defined. When this macro _is_ defined, is seems to be implemented in terms of lower-level compiler intrinsics, which do a better job than the boost::is_convertible implementation.

Note: See TracTickets for help on using tickets.