Boost logo

Boost :

Subject: [boost] [variant] compatibility with move-constructible objects
From: Zachary Turner (divisortheory_at_[hidden])
Date: 2010-02-23 00:06:35


I have the following rough sequence of typedefs:

struct empty {};
typedef std::unique_ptr<foo> foo_ptr;
typedef std::unique_ptr<bar> bar_ptr;

typedef std::vector<foo_ptr> foo_ptr_vec;
typedef std::vector<bar_ptr> bar_ptr_vec;

typedef std::variant<empty, foo_ptr_vec, bar_ptr_vec> my_variant;

I then declare an instance of my_variant in a class, and make the class
moveable and noncopyable.

class my_class
{
    my_class(const my_class&);
    my_class& my_class(const my_class&);

    my_variant v_;

public:
    my_class(my_class&& other)
        : v_(std::move(other.v_))
   {
   }
};

I cannot get this to compile under MSVC 10 and boost 1.42. In theory I
don't see why this shouldn't be ok. Even though the objects are not
copy-constructible due to unique_ptr, they are move constructible. The
errors are quite long, but you can see it's trying to invoke
vector::operator= from within the variant code.

Is this just a technical limitation of variant, or a bug?

1> behavior_collection.cpp
1>C:\Program Files (x86)\Microsoft Visual Studio
10.0\VC\include\xutility(2144): error C2248:
'behavior_collection::behavior_impl<Output>::operator =' : cannot access
private member declared in class
'behavior_collection::behavior_impl<Output>'
1> with
1> [
1> Output=kinematic_output
1> ]
1> c:\users\zach\documents\visual studio
2010\projects\dxdemo\dxdemo\behavior_collection.h(15) : see declaration of
'behavior_collection::behavior_impl<Output>::operator ='
1> with
1> [
1> Output=kinematic_output
1> ]
1> C:\Program Files (x86)\Microsoft Visual Studio
10.0\VC\include\xutility(2165) : see reference to function template
instantiation '_OutIt
std::_Copy_impl<_InIt,_OutIt>(_InIt,_InIt,_OutIt,std::_Nonscalar_ptr_iterator_tag)'
being compiled
1> with
1> [
1> _OutIt=behavior_collection::behavior_impl<kinematic_output>
*,
1> _InIt=behavior_collection::behavior_impl<kinematic_output> *
1> ]
1> C:\Program Files (x86)\Microsoft Visual Studio
10.0\VC\include\vector(719) : see reference to function template
instantiation '_OutIt
std::_Copy_impl<behavior_collection::behavior_impl<Output>*,behavior_collection::behavior_impl<Output>*>(_InIt,_InIt,_OutIt)'
being compiled
1> with
1> [
1> _OutIt=behavior_collection::behavior_impl<kinematic_output>
*,
1> Output=kinematic_output,
1> _InIt=behavior_collection::behavior_impl<kinematic_output> *
1> ]
1> C:\Program Files (x86)\Microsoft Visual Studio
10.0\VC\include\vector(709) : while compiling class template member function
'std::vector<_Ty> &std::vector<_Ty>::operator =(const std::vector<_Ty> &)'
1> with
1> [
1> _Ty=behavior_collection::behavior_impl<kinematic_output>
1> ]
1> C:\dev\boost\1.42.0\boost/type_traits/is_pod.hpp(34) : see
reference to class template instantiation 'std::vector<_Ty>' being compiled
1> with
1> [
1> _Ty=behavior_collection::behavior_impl<kinematic_output>
1> ]
1> C:\dev\boost\1.42.0\boost/type_traits/is_pod.hpp(129) : see
reference to class template instantiation 'boost::detail::is_pod_impl<T>'
being compiled
1> with
1> [
1>
 T=std::vector<behavior_collection::behavior_impl<kinematic_output>>
1> ]
1>
 C:\dev\boost\1.42.0\boost/type_traits/has_trivial_constructor.hpp(27) : see
reference to class template instantiation 'boost::is_pod<T>' being compiled
1> with
1> [
1>
 T=std::vector<behavior_collection::behavior_impl<kinematic_output>>
1> ]
1>
 C:\dev\boost\1.42.0\boost/type_traits/has_trivial_constructor.hpp(36) : see
reference to class template instantiation
'boost::detail::has_trivial_ctor_impl<T>' being compiled
1> with
1> [
1>
 T=std::vector<behavior_collection::behavior_impl<kinematic_output>>
1> ]
1>
 C:\dev\boost\1.42.0\boost/type_traits/has_nothrow_constructor.hpp(23) : see
reference to class template instantiation
'boost::has_trivial_constructor<T>' being compiled
1> with
1> [
1>
 T=std::vector<behavior_collection::behavior_impl<kinematic_output>>
1> ]
1>
 C:\dev\boost\1.42.0\boost/type_traits/has_nothrow_constructor.hpp(32) : see
reference to class template instantiation
'boost::detail::has_nothrow_constructor_imp<T>' being compiled
1> with
1> [
1>
 T=std::vector<behavior_collection::behavior_impl<kinematic_output>>
1> ]
1> C:\dev\boost\1.42.0\boost/mpl/not.hpp(41) : see reference to
class template instantiation 'boost::has_nothrow_constructor<T>' being
compiled
1> with
1> [
1>
 T=std::vector<behavior_collection::behavior_impl<kinematic_output>>
1> ]
1>
 C:\dev\boost\1.42.0\boost/mpl/aux_/preprocessed/plain/and.hpp(25) : see
reference to class template instantiation 'boost::mpl::not_<T>' being
compiled
1> with
1> [
1>
 T=boost::has_nothrow_constructor<std::vector<behavior_collection::behavior_impl<kinematic_output>>>
1> ]
1>
 C:\dev\boost\1.42.0\boost/mpl/aux_/preprocessed/plain/and.hpp(55) : see
reference to class template instantiation
'boost::mpl::aux::and_impl<C_,T1,T2,T3,T4>' being compiled
1> with
1> [
1> C_=true,
1>
 T1=boost::mpl::apply1<boost::mpl::protect<boost::detail::variant::find_fallback_type_pred>,boost::mpl::l_iter<boost::mpl::l_item<boost::mpl::long_<2>,std::vector<behavior_collection::behavior_impl<kinematic_output>>,boost::mpl::l_item<boost::mpl::long_<1>,std::vector<behavior_collection::behavior_impl<dynamic_output>>,boost::mpl::l_end>>>>,
1> T2=boost::mpl::true_,
1> T3=boost::mpl::true_,
1> T4=boost::mpl::true_
1> ]
1> C:\dev\boost\1.42.0\boost/mpl/iter_fold_if.hpp(46) : see
reference to class template instantiation 'boost::mpl::and_<T1,T2>' being
compiled
1> with
1> [
1>
 T1=boost::mpl::not_<boost::is_same<boost::mpl::l_iter<boost::mpl::l_item<boost::mpl::long_<2>,std::vector<behavior_collection::behavior_impl<kinematic_output>>,boost::mpl::l_item<boost::mpl::long_<1>,std::vector<behavior_collection::behavior_impl<dynamic_output>>,boost::mpl::l_end>>>,boost::mpl::l_iter<boost::mpl::l_end>>>,
1>
 T2=boost::mpl::apply1<boost::mpl::protect<boost::detail::variant::find_fallback_type_pred>,boost::mpl::l_iter<boost::mpl::l_item<boost::mpl::long_<2>,std::vector<behavior_collection::behavior_impl<kinematic_output>>,boost::mpl::l_item<boost::mpl::long_<1>,std::vector<behavior_collection::behavior_impl<dynamic_output>>,boost::mpl::l_end>>>>
1> ]
1>
 C:\dev\boost\1.42.0\boost/mpl/aux_/preprocessed/plain/apply_wrap.hpp(49) :
see reference to class template instantiation
'boost::mpl::aux::iter_fold_if_pred<Predicate,LastIterator>::apply<State,Iterator>'
being compiled
1> with
1> [
1>
 Predicate=boost::mpl::protect<boost::detail::variant::find_fallback_type_pred>,
1> LastIterator=boost::mpl::l_iter<boost::mpl::l_end>,
1> State=boost::mpl::int_<1>,
1>
 Iterator=boost::mpl::l_iter<boost::mpl::l_item<boost::mpl::long_<2>,std::vector<behavior_collection::behavior_impl<kinematic_output>>,boost::mpl::l_item<boost::mpl::long_<1>,std::vector<behavior_collection::behavior_impl<dynamic_output>>,boost::mpl::l_end>>>
1> ]
1>
 C:\dev\boost\1.42.0\boost/mpl/aux_/preprocessed/plain/apply.hpp(63) : see
reference to class template instantiation 'boost::mpl::apply_wrap2<F,T1,T2>'
being compiled
1> with
1> [
1>
 F=boost::mpl::protect<boost::mpl::aux::iter_fold_if_pred<boost::mpl::protect<boost::detail::variant::find_fallback_type_pred>,boost::mpl::l_iter<boost::mpl::l_end>>>,
1> T1=boost::mpl::int_<1>,
1>
 T2=boost::mpl::l_iter<boost::mpl::l_item<boost::mpl::long_<2>,std::vector<behavior_collection::behavior_impl<kinematic_output>>,boost::mpl::l_item<boost::mpl::long_<1>,std::vector<behavior_collection::behavior_impl<dynamic_output>>,boost::mpl::l_end>>>
1> ]
1>
 C:\dev\boost\1.42.0\boost/mpl/aux_/preprocessed/plain/iter_fold_if_impl.hpp(62)
: see reference to class template instantiation
'boost::mpl::apply2<F,T1,T2>' being compiled
1> with
1> [
1>
 F=boost::mpl::protect<boost::mpl::aux::iter_fold_if_pred<boost::mpl::protect<boost::detail::variant::find_fallback_type_pred>,boost::mpl::l_iter<boost::mpl::l_end>>>,
1> T1=boost::mpl::int_<1>,
1>
 T2=boost::mpl::l_iter<boost::mpl::l_item<boost::mpl::long_<2>,std::vector<behavior_collection::behavior_impl<kinematic_output>>,boost::mpl::l_item<boost::mpl::long_<1>,std::vector<behavior_collection::behavior_impl<dynamic_output>>,boost::mpl::l_end>>>
1> ]
1>
 C:\dev\boost\1.42.0\boost/mpl/aux_/preprocessed/plain/iter_fold_if_impl.hpp(102)
: see reference to class template instantiation
'boost::mpl::aux::iter_fold_if_forward_step<Iterator,State,ForwardOp,Predicate>'
being compiled
1> with
1> [
1>
 Iterator=boost::mpl::l_iter<boost::mpl::l_item<boost::mpl::long_<2>,std::vector<behavior_collection::behavior_impl<kinematic_output>>,boost::mpl::l_item<boost::mpl::long_<1>,std::vector<behavior_collection::behavior_impl<dynamic_output>>,boost::mpl::l_end>>>,
1> State=boost::mpl::int_<1>,
1>
 ForwardOp=boost::mpl::protect<boost::mpl::next<boost::mpl::na>>,
1>
 Predicate=boost::mpl::protect<boost::mpl::aux::iter_fold_if_pred<boost::mpl::protect<boost::detail::variant::find_fallback_type_pred>,boost::mpl::l_iter<boost::mpl::l_end>>>
1> ]
1> C:\dev\boost\1.42.0\boost/mpl/iter_fold_if.hpp(94) : see
reference to class template instantiation
'boost::mpl::aux::iter_fold_if_impl<Iterator,State,ForwardOp,ForwardPredicate,BackwardOp,BackwardPredicate>'
being compiled
1> with
1> [
1>
 Iterator=boost::mpl::l_iter<boost::mpl::l_item<boost::mpl::long_<3>,behavior_collection::null_behavior,boost::mpl::l_item<boost::mpl::long_<2>,std::vector<behavior_collection::behavior_impl<kinematic_output>>,boost::mpl::l_item<boost::mpl::long_<1>,std::vector<behavior_collection::behavior_impl<dynamic_output>>,boost::mpl::l_end>>>>,
1> State=boost::mpl::int_<0>,
1>
 ForwardOp=boost::mpl::protect<boost::mpl::next<boost::mpl::na>>,
1>
 ForwardPredicate=boost::mpl::protect<boost::mpl::aux::iter_fold_if_pred<boost::mpl::protect<boost::detail::variant::find_fallback_type_pred>,boost::mpl::l_iter<boost::mpl::l_end>>>,
1> BackwardOp=boost::mpl::na,
1> BackwardPredicate=boost::mpl::always<boost::mpl::false_>
1> ]
1> C:\dev\boost\1.42.0\boost/mpl/iter_fold_if.hpp(102) : see
reference to class template instantiation
'boost::mpl::iter_fold_if<Sequence,State,ForwardOp,ForwardPredicate>::result_'
being compiled
1> with
1> [
1>
 Sequence=boost::mpl::l_item<boost::mpl::long_<3>,behavior_collection::null_behavior,boost::mpl::l_item<boost::mpl::long_<2>,std::vector<behavior_collection::behavior_impl<kinematic_output>>,boost::mpl::l_item<boost::mpl::long_<1>,std::vector<behavior_collection::behavior_impl<dynamic_output>>,boost::mpl::l_end>>>,
1> State=boost::mpl::int_<0>,
1>
 ForwardOp=boost::mpl::protect<boost::mpl::next<boost::mpl::na>>,
1>
 ForwardPredicate=boost::mpl::protect<boost::detail::variant::find_fallback_type_pred>
1> ]
1> C:\dev\boost\1.42.0\boost/variant/variant.hpp(170) : see
reference to class template instantiation
'boost::mpl::iter_fold_if<Sequence,State,ForwardOp,ForwardPredicate>' being
compiled
1> with
1> [
1>
 Sequence=boost::mpl::l_item<boost::mpl::long_<3>,behavior_collection::null_behavior,boost::mpl::l_item<boost::mpl::long_<2>,std::vector<behavior_collection::behavior_impl<kinematic_output>>,boost::mpl::l_item<boost::mpl::long_<1>,std::vector<behavior_collection::behavior_impl<dynamic_output>>,boost::mpl::l_end>>>,
1> State=boost::mpl::int_<0>,
1>
 ForwardOp=boost::mpl::protect<boost::mpl::next<boost::mpl::na>>,
1>
 ForwardPredicate=boost::mpl::protect<boost::detail::variant::find_fallback_type_pred>
1> ]
1> C:\dev\boost\1.42.0\boost/variant/variant.hpp(1079) : see
reference to class template instantiation
'boost::detail::variant::find_fallback_type<Types>' being compiled
1> with
1> [
1>
 Types=boost::mpl::l_item<boost::mpl::long_<3>,behavior_collection::null_behavior,boost::mpl::l_item<boost::mpl::long_<2>,std::vector<behavior_collection::behavior_impl<kinematic_output>>,boost::mpl::l_item<boost::mpl::long_<1>,std::vector<behavior_collection::behavior_impl<dynamic_output>>,boost::mpl::l_end>>>
1> ]
1> c:\users\zach\documents\visual studio
2010\projects\dxdemo\dxdemo\behavior_collection.h(39) : see reference to
class template instantiation 'boost::variant<T0_,T1,T2>' being compiled
1> with
1> [
1> T0_=behavior_collection::null_behavior,
1> T1=behavior_collection::kinematic_behaviors,
1> T2=behavior_collection::dynamic_behaviors
1> ]


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk