Modify

Ticket #7120 (closed Bugs: fixed)

Opened 5 years ago

Last modified 8 days ago

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:

Description

#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

Change History

comment:1 Changed 11 months ago by apolukhin

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

comment:2 follow-up: ↓ 4 Changed 11 months ago by apolukhin

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

comment:3 Changed 10 months ago by anonymous

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

comment:4 in reply to: ↑ 2 Changed 8 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, 
  boost::recursive_wrapper<node1_type<var_type>>
>;

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 3 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 8 days ago by apolukhin

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

Add a comment

Modify Ticket

Change Properties
<Author field>
Action
as closed
The resolution will be deleted. Next status will be 'reopened'
Author


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

 
Note: See TracTickets for help on using tickets.