[1.43.0] [variant] Compilation errors when swapping variant type objects

We are using Boost 1.43.0 (we tried to move to 1.44.0 but there were some problems which I reported some time ago) in Visual Studio 2010. And there are some compilation problems when variant type objects are swapped. This does not affect all variant types but I didn't figured out what are the exact conditions (however I guess it is likely something with namespaces and templates). Following code demonstrates the issue: ---------------------------------------- #include <cstdlib> #include <list> #include <boost/variant.hpp> int main() { typedef boost::variant< std::list< int >::iterator > variant_type; variant_type v; variant_type().swap( v ); return EXIT_SUCCESS; } ---------------------------------------- compilation fails with following message: ---------------------------------------- 1>d:\libraries\boost_1_43_0\boost\variant\detail\move.hpp(155): error C2668: 'boost::detail::variant::detail::move_swap::swap' : ambiguous call to overloaded function 1> d:\libraries\boost_1_43_0\boost\variant\detail\move.hpp(141): could be 'void boost::detail::variant::detail::move_swap::swap<T>(T &,T &)' 1> with 1> [ 1> T=T0 1> ] 1> c:\program files\microsoft visual studio 10.0\vc\include\utility(100): or 'void std::swap<T>(_Ty &,_Ty &)' [found using argument-dependent lookup] 1> with 1> [ 1> T=T0, 1> _Ty=T0 1> ] 1> while trying to match the argument list '(T0, T0)' 1> d:\libraries\boost_1_43_0\boost\variant\variant.hpp(698) : see reference to function template instantiation 'void boost::detail::variant::move_swap<T>(T &,T &)' being compiled 1> with 1> [ 1> T=T0 1> ] 1> d:\libraries\boost_1_43_0\boost\variant\variant.hpp(825) : see reference to function template instantiation 'void boost::detail::variant::swap_with<Variant>::operator ()<T>(T &) const' being compiled 1> with 1> [ 1> Variant=boost::variant<std::_List_iterator<std::_List_val<int,std::allocator<int>>>>, 1> T=T0 1> ] 1> d:\libraries\boost_1_43_0\boost\variant\detail\visitation_impl.hpp(141) : see reference to function template instantiation 'void boost::detail::variant::invoke_visitor<Visitor>::internal_visit<T>(T &,int)' being compiled 1> with 1> [ 1> Visitor=boost::detail::variant::swap_with<boost::variant<std::_List_iterator<std::_List_val<int,std::allocator<int>>>>>, 1> T=T0 1> ] 1> d:\libraries\boost_1_43_0\boost\variant\detail\visitation_impl.hpp(169) : see reference to function template instantiation 'void boost::detail::variant::visitation_impl_invoke_impl<Visitor,VoidPtrCV,T>(int,Visitor &,VoidPtrCV,T *,boost::mpl::false_)' being compiled 1> with 1> [ 1> Visitor=boost::detail::variant::invoke_visitor<boost::detail::variant::swap_with<boost::variant<std::_List_iterator<std::_List_val<int,std::allocator<int>>>>>>, 1> VoidPtrCV=void *, 1> T=T0 1> ] 1> d:\libraries\boost_1_43_0\boost\variant\detail\visitation_impl.hpp(252) : see reference to function template instantiation 'void boost::detail::variant::visitation_impl_invoke<Visitor,VoidPtrCV,T0,NoBackupFlag>(int,Visitor &,VoidPtrCV,T *,NoBackupFlag,int)' being compiled 1> with 1> [ 1> Visitor=boost::detail::variant::invoke_visitor<boost::detail::variant::swap_with<boost::variant<std::_List_iterator<std::_List_val<int,std::allocator<int>>>>>>, 1> VoidPtrCV=void *, 1> NoBackupFlag=boost::variant<std::_List_iterator<std::_List_val<int,std::allocator<int>>>>::has_fallback_type_, 1> T=T0 1> ] 1> d:\libraries\boost_1_43_0\boost\variant\variant.hpp(1769) : see reference to function template instantiation 'void boost::detail::variant::visitation_impl<first_which,first_step,Visitor,VoidPtrCV,boost::variant<T0_>::has_fallback_type_>(const int,const int,Visitor &,VoidPtrCV,boost::mpl::false_,NoBackupFlag,Which *,step0 *)' being compiled 1> with 1> [ 1> Visitor=boost::detail::variant::invoke_visitor<boost::detail::variant::swap_with<boost::variant<std::_List_iterator<std::_List_val<int,std::allocator<int>>>>>>, 1> VoidPtrCV=void *, 1> T0_=std::_List_iterator<std::_List_val<int,std::allocator<int>>>, 1> NoBackupFlag=boost::variant<std::_List_iterator<std::_List_val<int,std::allocator<int>>>>::has_fallback_type_, 1> Which=first_which, 1> step0=first_step 1> ] 1> d:\libraries\boost_1_43_0\boost\variant\variant.hpp(1780) : see reference to function template instantiation 'void boost::variant<T0_>::internal_apply_visitor_impl<Visitor,void*>(int,int,Visitor &,VoidPtrCV)' being compiled 1> with 1> [ 1> T0_=std::_List_iterator<std::_List_val<int,std::allocator<int>>>, 1> Visitor=boost::detail::variant::invoke_visitor<boost::detail::variant::swap_with<boost::variant<std::_List_iterator<std::_List_val<int,std::allocator<int>>>>>>, 1> VoidPtrCV=void * 1> ] 1> d:\libraries\boost_1_43_0\boost\variant\variant.hpp(1803) : see reference to function template instantiation 'void boost::variant<T0_>::internal_apply_visitor<boost::detail::variant::invoke_visitor<Visitor>>(boost::detail::variant::invoke_visitor<Visitor> &)' being compiled 1> with 1> [ 1> T0_=std::_List_iterator<std::_List_val<int,std::allocator<int>>>, 1> Visitor=boost::detail::variant::swap_with<boost::variant<std::_List_iterator<std::_List_val<int,std::allocator<int>>>>> 1> ] 1> d:\libraries\boost_1_43_0\boost\variant\variant.hpp(1637) : see reference to function template instantiation 'void boost::variant<T0_>::apply_visitor<boost::detail::variant::swap_with<Variant>>(Visitor &)' being compiled 1> with 1> [ 1> T0_=std::_List_iterator<std::_List_val<int,std::allocator<int>>>, 1> Variant=boost::variant<std::_List_iterator<std::_List_val<int,std::allocator<int>>>>, 1> Visitor=boost::detail::variant::swap_with<boost::variant<std::_List_iterator<std::_List_val<int,std::allocator<int>>>>> 1> ] 1> d:\libraries\boost_1_43_0\boost\variant\variant.hpp(1631) : while compiling class template member function 'void boost::variant<T0_>::swap(boost::variant<T0_> &)' 1> with 1> [ 1> T0_=std::_List_iterator<std::_List_val<int,std::allocator<int>>> 1> ] 1> d:\test\simple\simple.cpp(10) : see reference to class template instantiation 'boost::variant<T0_>' being compiled 1> with 1> [ 1> T0_=std::_List_iterator<std::_List_val<int,std::allocator<int>>> 1> ] ---------------------------------------- Adam Badura

On 9/28/2010 10:50 PM, Adam Badura wrote:
We are using Boost 1.43.0 (we tried to move to 1.44.0 but there were some problems which I reported some time ago) in Visual Studio 2010. And there are some compilation problems when variant type objects are swapped. This does not affect all variant types but I didn't figured out what are the exact conditions (however I guess it is likely something with namespaces and templates).
Following code demonstrates the issue: ---------------------------------------- #include <cstdlib> #include <list> #include <boost/variant.hpp>
int main() { typedef boost::variant< std::list< int >::iterator > variant_type;
variant_type v; variant_type().swap( v );
return EXIT_SUCCESS; } ----------------------------------------
compilation fails with following message: ---------------------------------------- 1>d:\libraries\boost_1_43_0\boost\variant\detail\move.hpp(155): error C2668: 'boost::detail::variant::detail::move_swap::swap' : ambiguous call to overloaded function 1> d:\libraries\boost_1_43_0\boost\variant\detail\move.hpp(141): could be 'void boost::detail::variant::detail::move_swap::swap<T>(T &,T &)' 1> with 1> [ 1> T=T0 1> ] 1> c:\program files\microsoft visual studio 10.0\vc\include\utility(100): or 'void std::swap<T>(_Ty &,_Ty &)' [found using argument-dependent lookup] 1> with 1> [ 1> T=T0, 1> _Ty=T0 1> ] 1> while trying to match the argument list '(T0, T0)' [...]
Local changes you can make to get a quick fix (I hope): Try expressing the implementation of boost::detail::move_swap in terms of 2 independent template parameters, rather than 1: template <typename T,typename U> inline void swap(T& lhs, U& rhs) { T tmp( boost::detail::variant::move(lhs) ); lhs = boost::detail::variant::move(rhs); rhs = boost::detail::variant::move(tmp); } This is the same "trick" that boost::swap uses to avoid ambiguity with std::swap, I believe; see the comment in boost/utility/swap.hpp. I verified that this fixes your issue on MSVC9, at least. I don't have boost 1.44 installed (yet), but you might want to check if it looks like the same problem exists there, and if it does, file a trac ticket...? - Jeff

I verified that this fixes your issue on MSVC9, at least.
I don't have boost 1.44 installed (yet), but you might want to check if it looks like the same problem exists there, and if it does, file a trac ticket...?
I don't have it as well. But if I had to guess I would bet that the problem exists on 1.44 as well. Adam Badura
participants (2)
-
Adam Badura
-
Jeffrey Lee Hellrung, Jr.