Opened 5 years ago

Closed 2 months ago

#7120 closed Bugs (fixed)

ambiguous overload of convert_construct in variant when one of variant's value types derives from variant

Reported by: jeffrey.hellrung Owned by: apolukhin
Milestone: Boost 1.64.0 Component: variant
Version: Boost 1.51.0 Severity: Problem
Keywords: Cc:


#include <boost/variant.hpp>

struct X

: boost::variant< int >

{ };

void main() {

X x; boost::variant<X> y(x);


yields (MSVC9)

1>------ Build started: Project: scratch, Configuration: Debug Win32 ------ 1>Compiling... 1>main.cpp 1>c:\users\jeffrey\boost_1_49_0\boost\variant\variant.hpp(1405) : error C2666: 'boost::variant<T0_>::convert_construct' : 3 overloads have similar conversions 1> with 1> [ 1> T0_=X 1> ] 1> c:\users\jeffrey\boost_1_49_0\boost\variant\variant.hpp(1384): could be 'void boost::variant<T0_>::convert_construct<int,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_>(const boost::variant<int> &,long)' 1> with 1> [ 1> T0_=X 1> ] 1> c:\users\jeffrey\boost_1_49_0\boost\variant\variant.hpp(1375): or 'void boost::variant<T0_>::convert_construct<int,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_>(boost::variant<int> &,long)' 1> with 1> [ 1> T0_=X 1> ] 1> c:\users\jeffrey\boost_1_49_0\boost\variant\variant.hpp(1315): or 'void boost::variant<T0_>::convert_construct<T>(T &,int,boost::mpl::false_)' 1> with 1> [ 1> T0_=X, 1> T=X 1> ] 1> while trying to match the argument list '(X, long)' 1> c:\users\jeffrey\scratch\main.cpp(10) : see reference to function template instantiation 'boost::variant<T0_>::variant<X>(T &)' being compiled 1> with 1> [ 1> T0_=X, 1> T=X 1> ]

Basically, the problem appears to be the call to

convert_construct(operand, 1L) operand is of type X

which cannot disambiguate between the overloads (simplified)

void convert_construct([const] boost::variant<T>& operand, long); void convert_construct(T& operand, int);

The former requires a derived->base conversion in the first argument, while the latter requires a long->int conversion in the second argument. Perhaps the dispatching among the convert_construct overloads should be more sophisticated?

Attachments (0)

Change History (6)

comment:1 Changed 13 months ago by apolukhin

  • Milestone changed from To Be Determined to Boost 1.62.0
  • Owner changed from ebf to apolukhin
  • Status changed from new to assigned

comment:2 follow-up: Changed 13 months ago by apolukhin

Fixed in d23cdd35 develop, will be merged to master branch as soon as the tests will cycle.

comment:3 Changed 12 months ago by anonymous

Any workaround for this? I have the exact same problem.

comment:4 in reply to: ↑ 2 Changed 10 months ago by Igor R.

Replying to apolukhin:

Fixed in d23cdd35 develop, will be merged to master branch as soon as the tests will cycle.

Just for the record: the proposed fix fails the following code:

#include <boost/variant.hpp>
#include <array>

template<class Node>
struct node1_type;

struct var_type;

using var_base = boost::variant<int, 

template<class Node>
struct node1_type
  std::array<Node, 1> children;

struct var_type : var_base
  using var_base::var_base;

int main()
  var_type v1 = 1;

comment:5 Changed 5 months ago by apolukhin

  • Milestone changed from Boost 1.62.0 to Boost 1.64.0

Fixed by Mikhail Maximov in 217ee7f9. Test case was added in fbad41fb. As soon as the tests will cycle, will be merged to master branch.

comment:6 Changed 2 months ago by apolukhin

  • Resolution set to fixed
  • Status changed from assigned to closed

Add Comment

Modify Ticket

Change Properties
Set your email in Preferences
as closed The owner will remain apolukhin.
The resolution will be deleted. Next status will be 'reopened'.

E-mail address and user name can be saved in the Preferences.

Note: See TracTickets for help on using tickets.