The following code fails to compile with g++ 4.7.3 when the -std=c++11 flag is set (error message pasted at the bottom):
#include <boost/variant.hpp>
#include <boost/shared_ptr.hpp>
int main() {
boost::shared_ptr<int> i;
boost::variant< boost::shared_ptr<int> > v;
v = i;
return 0;
}
The Boost version is 1.54. It compiles without error when std=c++11 is not set and also with clang 3.4 (with or without -std=c++11). I'm pretty sure this should be valid code, so is this a g++ problem or a boost problem? If so, what is the bug, exactly?
Here's the error message:
In file included from /usr/local/include/boost/variant.hpp:17:0,
from vartest.cpp:1:
/usr/local/include/boost/variant/variant.hpp: In instantiation of ‘void boost::variant<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19>::move_assigner::internal_visit(RhsT&, int) [with RhsT = boost::shared_ptr<int>; T0_ = boost::shared_ptr<int>; T1 = boost::detail::variant::void_; T2 = boost::detail::variant::void_; T3 = boost::detail::variant::void_; T4 = boost::detail::variant::void_; T5 = boost::detail::variant::void_; T6 = boost::detail::variant::void_; T7 = boost::detail::variant::void_; T8 = boost::detail::variant::void_; T9 = boost::detail::variant::void_; T10 = boost::detail::variant::void_; T11 = boost::detail::variant::void_; T12 = boost::detail::variant::void_; T13 = boost::detail::variant::void_; T14 = boost::detail::variant::void_; T15 = boost::detail::variant::void_; T16 = boost::detail::variant::void_; T17 = boost::detail::variant::void_; T18 = boost::detail::variant::void_; T19 = boost::detail::variant::void_]’:
/usr/local/include/boost/variant/detail/visitation_impl.hpp:130:9: required from ‘typename Visitor::result_type boost::detail::variant::visitation_impl_invoke_impl(int, Visitor&, VoidPtrCV, T*, mpl_::true_) [with Visitor = boost::variant<boost::shared_ptr<int> >::move_assigner; VoidPtrCV = void*; T = boost::shared_ptr<int>; typename Visitor::result_type = void; mpl_::true_ = mpl_::bool_<true>]’
/usr/local/include/boost/variant/detail/visitation_impl.hpp:173:9: required from ‘typename Visitor::result_type boost::detail::variant::visitation_impl_invoke(int, Visitor&, VoidPtrCV, T*, NoBackupFlag, int) [with Visitor = boost::variant<boost::shared_ptr<int> >::move_assigner; VoidPtrCV = void*; T = boost::shared_ptr<int>; NoBackupFlag = boost::variant<boost::shared_ptr<int> >::has_fallback_type_; typename Visitor::result_type = void]’
/usr/local/include/boost/variant/detail/visitation_impl.hpp:260:1: required from ‘typename Visitor::result_type boost::detail::variant::visitation_impl(int, int, Visitor&, VoidPtrCV, mpl_::false_, NoBackupFlag, Which*, step0*) [with Which = mpl_::int_<0>; step0 = boost::detail::variant::visitation_impl_step<boost::mpl::l_iter<boost::mpl::l_item<mpl_::long_<1l>, boost::shared_ptr<int>, boost::mpl::l_end> >, boost::mpl::l_iter<boost::mpl::l_end> >; Visitor = boost::variant<boost::shared_ptr<int> >::move_assigner; VoidPtrCV = void*; NoBackupFlag = boost::variant<boost::shared_ptr<int> >::has_fallback_type_; typename Visitor::result_type = void; mpl_::false_ = mpl_::bool_<false>]’
/usr/local/include/boost/variant/variant.hpp:2326:13: required from ‘static typename Visitor::result_type boost::variant<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19>::internal_apply_visitor_impl(int, int, Visitor&, VoidPtrCV) [with Visitor = boost::variant<boost::shared_ptr<int> >::move_assigner; VoidPtrCV = void*; T0_ = boost::shared_ptr<int>; T1 = boost::detail::variant::void_; T2 = boost::detail::variant::void_; T3 = boost::detail::variant::void_; T4 = boost::detail::variant::void_; T5 = boost::detail::variant::void_; T6 = boost::detail::variant::void_; T7 = boost::detail::variant::void_; T8 = boost::detail::variant::void_; T9 = boost::detail::variant::void_; T10 = boost::detail::variant::void_; T11 = boost::detail::variant::void_; T12 = boost::detail::variant::void_; T13 = boost::detail::variant::void_; T14 = boost::detail::variant::void_; T15 = boost::detail::variant::void_; T16 = boost::detail::variant::void_; T17 = boost::detail::variant::void_; T18 = boost::detail::variant::void_; T19 = boost::detail::variant::void_; typename Visitor::result_type = void]’
/usr/local/include/boost/variant/variant.hpp:2337:13: required from ‘typename Visitor::result_type boost::variant<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19>::internal_apply_visitor(Visitor&) [with Visitor = boost::variant<boost::shared_ptr<int> >::move_assigner; T0_ = boost::shared_ptr<int>; T1 = boost::detail::variant::void_; T2 = boost::detail::variant::void_; T3 = boost::detail::variant::void_; T4 = boost::detail::variant::void_; T5 = boost::detail::variant::void_; T6 = boost::detail::variant::void_; T7 = boost::detail::variant::void_; T8 = boost::detail::variant::void_; T9 = boost::detail::variant::void_; T10 = boost::detail::variant::void_; T11 = boost::detail::variant::void_; T12 = boost::detail::variant::void_; T13 = boost::detail::variant::void_; T14 = boost::detail::variant::void_; T15 = boost::detail::variant::void_; T16 = boost::detail::variant::void_; T17 = boost::detail::variant::void_; T18 = boost::detail::variant::void_; T19 = boost::detail::variant::void_; typename Visitor::result_type = void]’
/usr/local/include/boost/variant/variant.hpp:2109:13: required from ‘void boost::variant<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19>::variant_assign(boost::variant<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19>&&) [with T0_ = boost::shared_ptr<int>; T1 = boost::detail::variant::void_; T2 = boost::detail::variant::void_; T3 = boost::detail::variant::void_; T4 = boost::detail::variant::void_; T5 = boost::detail::variant::void_; T6 = boost::detail::variant::void_; T7 = boost::detail::variant::void_; T8 = boost::detail::variant::void_; T9 = boost::detail::variant::void_; T10 = boost::detail::variant::void_; T11 = boost::detail::variant::void_; T12 = boost::detail::variant::void_; T13 = boost::detail::variant::void_; T14 = boost::detail::variant::void_; T15 = boost::detail::variant::void_; T16 = boost::detail::variant::void_; T17 = boost::detail::variant::void_; T18 = boost::detail::variant::void_; T19 = boost::detail::variant::void_; boost::variant<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19> = boost::variant<boost::shared_ptr<int> >]’
/usr/local/include/boost/variant/variant.hpp:2130:13: required from ‘void boost::variant<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19>::assign(const T&) [with T = boost::shared_ptr<int>; T0_ = boost::shared_ptr<int>; T1 = boost::detail::variant::void_; T2 = boost::detail::variant::void_; T3 = boost::detail::variant::void_; T4 = boost::detail::variant::void_; T5 = boost::detail::variant::void_; T6 = boost::detail::variant::void_; T7 = boost::detail::variant::void_; T8 = boost::detail::variant::void_; T9 = boost::detail::variant::void_; T10 = boost::detail::variant::void_; T11 = boost::detail::variant::void_; T12 = boost::detail::variant::void_; T13 = boost::detail::variant::void_; T14 = boost::detail::variant::void_; T15 = boost::detail::variant::void_; T16 = boost::detail::variant::void_; T17 = boost::detail::variant::void_; T18 = boost::detail::variant::void_; T19 = boost::detail::variant::void_]’
/usr/local/include/boost/variant/variant.hpp:2168:9: required from ‘boost::variant<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19>& boost::variant<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19>::operator=(const T&) [with T = boost::shared_ptr<int>; T0_ = boost::shared_ptr<int>; T1 = boost::detail::variant::void_; T2 = boost::detail::variant::void_; T3 = boost::detail::variant::void_; T4 = boost::detail::variant::void_; T5 = boost::detail::variant::void_; T6 = boost::detail::variant::void_; T7 = boost::detail::variant::void_; T8 = boost::detail::variant::void_; T9 = boost::detail::variant::void_; T10 = boost::detail::variant::void_; T11 = boost::detail::variant::void_; T12 = boost::detail::variant::void_; T13 = boost::detail::variant::void_; T14 = boost::detail::variant::void_; T15 = boost::detail::variant::void_; T16 = boost::detail::variant::void_; T17 = boost::detail::variant::void_; T18 = boost::detail::variant::void_; T19 = boost::detail::variant::void_; boost::variant<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19> = boost::variant<boost::shared_ptr<int> >]’
vartest.cpp:7:9: required from here
/usr/local/include/boost/variant/variant.hpp:2058:13: error: no matching function for call to ‘boost::variant<boost::shared_ptr<int> >::move_assigner::assign_impl(boost::shared_ptr<int>&, nothrow_copy, nothrow_move_constructor, boost::variant<boost::shared_ptr<int> >::has_fallback_type_)’
/usr/local/include/boost/variant/variant.hpp:2058:13: note: candidates are:
/usr/local/include/boost/variant/variant.hpp:1959:14: note: template<class RhsT, class B1, class B2> void boost::variant<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19>::move_assigner::assign_impl(RhsT&, mpl_::true_, mpl_::false_, B2) [with RhsT = RhsT; B1 = B1; B2 = B2; T0_ = boost::shared_ptr<int>; T1 = boost::detail::variant::void_; T2 = boost::detail::variant::void_; T3 = boost::detail::variant::void_; T4 = boost::detail::variant::void_; T5 = boost::detail::variant::void_; T6 = boost::detail::variant::void_; T7 = boost::detail::variant::void_; T8 = boost::detail::variant::void_; T9 = boost::detail::variant::void_; T10 = boost::detail::variant::void_; T11 = boost::detail::variant::void_; T12 = boost::detail::variant::void_; T13 = boost::detail::variant::void_; T14 = boost::detail::variant::void_; T15 = boost::detail::variant::void_; T16 = boost::detail::variant::void_; T17 = boost::detail::variant::void_; T18 = boost::detail::variant::void_; T19 = boost::detail::variant::void_]
/usr/local/include/boost/variant/variant.hpp:1959:14: note: template argument deduction/substitution failed:
/usr/local/include/boost/variant/variant.hpp:2058:13: note: couldn't deduce template parameter ‘B1’
/usr/local/include/boost/variant/variant.hpp:1978:14: note: template<class RhsT, class B> void boost::variant<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19>::move_assigner::assign_impl(RhsT&, mpl_::true_, mpl_::true_, B) [with RhsT = RhsT; B = B; T0_ = boost::shared_ptr<int>; T1 = boost::detail::variant::void_; T2 = boost::detail::variant::void_; T3 = boost::detail::variant::void_; T4 = boost::detail::variant::void_; T5 = boost::detail::variant::void_; T6 = boost::detail::variant::void_; T7 = boost::detail::variant::void_; T8 = boost::detail::variant::void_; T9 = boost::detail::variant::void_; T10 = boost::detail::variant::void_; T11 = boost::detail::variant::void_; T12 = boost::detail::variant::void_; T13 = boost::detail::variant::void_; T14 = boost::detail::variant::void_; T15 = boost::detail::variant::void_; T16 = boost::detail::variant::void_; T17 = boost::detail::variant::void_; T18 = boost::detail::variant::void_; T19 = boost::detail::variant::void_]
/usr/local/include/boost/variant/variant.hpp:1978:14: note: template argument deduction/substitution failed:
/usr/local/include/boost/variant/variant.hpp:2058:13: note: cannot convert ‘nothrow_move_constructor()’ (type ‘nothrow_move_constructor {aka boost::integral_constant<bool, false>}’) to type ‘mpl_::true_ {aka mpl_::bool_<true>}’
/usr/local/include/boost/variant/variant.hpp:1997:14: note: template<class RhsT> void boost::variant<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19>::move_assigner::assign_impl(RhsT&, mpl_::false_, mpl_::false_, mpl_::true_) [with RhsT = RhsT; T0_ = boost::shared_ptr<int>; T1 = boost::detail::variant::void_; T2 = boost::detail::variant::void_; T3 = boost::detail::variant::void_; T4 = boost::detail::variant::void_; T5 = boost::detail::variant::void_; T6 = boost::detail::variant::void_; T7 = boost::detail::variant::void_; T8 = boost::detail::variant::void_; T9 = boost::detail::variant::void_; T10 = boost::detail::variant::void_; T11 = boost::detail::variant::void_; T12 = boost::detail::variant::void_; T13 = boost::detail::variant::void_; T14 = boost::detail::variant::void_; T15 = boost::detail::variant::void_; T16 = boost::detail::variant::void_; T17 = boost::detail::variant::void_; T18 = boost::detail::variant::void_; T19 = boost::detail::variant::void_]
/usr/local/include/boost/variant/variant.hpp:1997:14: note: template argument deduction/substitution failed:
/usr/local/include/boost/variant/variant.hpp:2058:13: note: cannot convert ‘nothrow_copy()’ (type ‘nothrow_copy {aka mpl_::bool_<true>}’) to type ‘mpl_::false_ {aka mpl_::bool_<false>}’
/usr/local/include/boost/variant/variant.hpp:2033:14: note: template<class RhsT> void boost::variant<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19>::move_assigner::assign_impl(const RhsT&, mpl_::false_, mpl_::false_, mpl_::false_) [with RhsT = RhsT; T0_ = boost::shared_ptr<int>; T1 = boost::detail::variant::void_; T2 = boost::detail::variant::void_; T3 = boost::detail::variant::void_; T4 = boost::detail::variant::void_; T5 = boost::detail::variant::void_; T6 = boost::detail::variant::void_; T7 = boost::detail::variant::void_; T8 = boost::detail::variant::void_; T9 = boost::detail::variant::void_; T10 = boost::detail::variant::void_; T11 = boost::detail::variant::void_; T12 = boost::detail::variant::void_; T13 = boost::detail::variant::void_; T14 = boost::detail::variant::void_; T15 = boost::detail::variant::void_; T16 = boost::detail::variant::void_; T17 = boost::detail::variant::void_; T18 = boost::detail::variant::void_; T19 = boost::detail::variant::void_]
/usr/local/include/boost/variant/variant.hpp:2033:14: note: template argument deduction/substitution failed:
/usr/local/include/boost/variant/variant.hpp:2058:13: note: cannot convert ‘nothrow_copy()’ (type ‘nothrow_copy {aka mpl_::bool_<true>}’) to type ‘mpl_::false_ {aka mpl_::bool_<false>}’
Related
I am learning about boost::variant and accessing its members using apply_visitor. So, I wrote the following example.
I have pointers to templated objects as my class members. I would like to access them using apply_visitor.
//Example program
#include <iostream>
#include <map>
#include <string>
#include <boost/shared_ptr.hpp>
#include <boost/variant.hpp>
#include <boost/any.hpp>
class A {
template<size_t dim>
struct C : boost::static_visitor<C<dim> *>{
int x;
C() {
x = dim;
}
template <size_t t>
C<t> * operator()(C<t> *s) const {
std::cout<<s->x<<std::endl;
return s;
}
};
public:
C<1>* Aasd;
C<2>* Bbsd;
std::map<std::string, boost::variant<C<2> *, C<1> * > > matrices;
A() {
Aasd = new C<1>;
Bbsd = new C<2>;
matrices.insert(std::make_pair("Bb", Bbsd));
boost::apply_visitor(C<2>(), matrices["Bb"]);
// boost::apply_visitor(C<1>(), matrices["Aa"]);
}
~A() {
delete Aasd;
delete Bbsd;
}
};
int main()
{
A a;
return 0;
}
The error that I get from compiling the above is
In file included from /usr/include/boost/variant.hpp:17:0,
from 8:
/usr/include/boost/variant/variant.hpp: In instantiation of 'boost::detail::variant::invoke_visitor<Visitor>::result_type boost::detail::variant::invoke_visitor<Visitor>::internal_visit(T&, int) [with T = A::C<1ul>*; Visitor = const A::C<2ul>; boost::detail::variant::invoke_visitor<Visitor>::result_type = A::C<2ul>*]':
/usr/include/boost/variant/detail/visitation_impl.hpp:130:9: required from 'typename Visitor::result_type boost::detail::variant::visitation_impl_invoke_impl(int, Visitor&, VoidPtrCV, T*, mpl_::true_) [with Visitor = boost::detail::variant::invoke_visitor<const A::C<2ul> >; VoidPtrCV = void*; T = A::C<1ul>*; typename Visitor::result_type = A::C<2ul>*; mpl_::true_ = mpl_::bool_<true>]'
/usr/include/boost/variant/detail/visitation_impl.hpp:173:9: required from 'typename Visitor::result_type boost::detail::variant::visitation_impl_invoke(int, Visitor&, VoidPtrCV, T*, NoBackupFlag, int) [with Visitor = boost::detail::variant::invoke_visitor<const A::C<2ul> >; VoidPtrCV = void*; T = A::C<1ul>*; NoBackupFlag = boost::variant<A::C<2ul>*, A::C<1ul>*>::has_fallback_type_; typename Visitor::result_type = A::C<2ul>*]'
/usr/include/boost/variant/detail/visitation_impl.hpp:256:5: required from 'typename Visitor::result_type boost::detail::variant::visitation_impl(int, int, Visitor&, VoidPtrCV, mpl_::false_, NoBackupFlag, Which*, step0*) [with Which = mpl_::int_<0>; step0 = boost::detail::variant::visitation_impl_step<boost::mpl::l_iter<boost::mpl::l_item<mpl_::long_<2l>, A::C<2ul>*, boost::mpl::l_item<mpl_::long_<1l>, A::C<1ul>*, boost::mpl::l_end> > >, boost::mpl::l_iter<boost::mpl::l_end> >; Visitor = boost::detail::variant::invoke_visitor<const A::C<2ul> >; VoidPtrCV = void*; NoBackupFlag = boost::variant<A::C<2ul>*, A::C<1ul>*>::has_fallback_type_; typename Visitor::result_type = A::C<2ul>*; mpl_::false_ = mpl_::bool_<false>]'
/usr/include/boost/variant/variant.hpp:2367:13: required from 'static typename Visitor::result_type boost::variant<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19>::internal_apply_visitor_impl(int, int, Visitor&, VoidPtrCV) [with Visitor = boost::detail::variant::invoke_visitor<const A::C<2ul> >; VoidPtrCV = void*; T0_ = A::C<2ul>*; T1 = A::C<1ul>*; T2 = boost::detail::variant::void_; T3 = boost::detail::variant::void_; T4 = boost::detail::variant::void_; T5 = boost::detail::variant::void_; T6 = boost::detail::variant::void_; T7 = boost::detail::variant::void_; T8 = boost::detail::variant::void_; T9 = boost::detail::variant::void_; T10 = boost::detail::variant::void_; T11 = boost::detail::variant::void_; T12 = boost::detail::variant::void_; T13 = boost::detail::variant::void_; T14 = boost::detail::variant::void_; T15 = boost::detail::variant::void_; T16 = boost::detail::variant::void_; T17 = boost::detail::variant::void_; T18 = boost::detail::variant::void_; T19 = boost::detail::variant::void_; typename Visitor::result_type = A::C<2ul>*]'
/usr/include/boost/variant/variant.hpp:2378:13: required from 'typename Visitor::result_type boost::variant<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19>::internal_apply_visitor(Visitor&) [with Visitor = boost::detail::variant::invoke_visitor<const A::C<2ul> >; T0_ = A::C<2ul>*; T1 = A::C<1ul>*; T2 = boost::detail::variant::void_; T3 = boost::detail::variant::void_; T4 = boost::detail::variant::void_; T5 = boost::detail::variant::void_; T6 = boost::detail::variant::void_; T7 = boost::detail::variant::void_; T8 = boost::detail::variant::void_; T9 = boost::detail::variant::void_; T10 = boost::detail::variant::void_; T11 = boost::detail::variant::void_; T12 = boost::detail::variant::void_; T13 = boost::detail::variant::void_; T14 = boost::detail::variant::void_; T15 = boost::detail::variant::void_; T16 = boost::detail::variant::void_; T17 = boost::detail::variant::void_; T18 = boost::detail::variant::void_; T19 = boost::detail::variant::void_; typename Visitor::result_type = A::C<2ul>*]'
/usr/include/boost/variant/variant.hpp:2401:52: required from 'typename Visitor::result_type boost::variant<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19>::apply_visitor(Visitor&) [with Visitor = const A::C<2ul>; T0_ = A::C<2ul>*; T1 = A::C<1ul>*; T2 = boost::detail::variant::void_; T3 = boost::detail::variant::void_; T4 = boost::detail::variant::void_; T5 = boost::detail::variant::void_; T6 = boost::detail::variant::void_; T7 = boost::detail::variant::void_; T8 = boost::detail::variant::void_; T9 = boost::detail::variant::void_; T10 = boost::detail::variant::void_; T11 = boost::detail::variant::void_; T12 = boost::detail::variant::void_; T13 = boost::detail::variant::void_; T14 = boost::detail::variant::void_; T15 = boost::detail::variant::void_; T16 = boost::detail::variant::void_; T17 = boost::detail::variant::void_; T18 = boost::detail::variant::void_; T19 = boost::detail::variant::void_; typename Visitor::result_type = A::C<2ul>*]'
/usr/include/boost/variant/detail/apply_visitor_unary.hpp:76:43: required from 'typename Visitor::result_type boost::apply_visitor(const Visitor&, Visitable&) [with Visitor = A::C<2ul>; Visitable = boost::variant<A::C<2ul>*, A::C<1ul>*>; typename Visitor::result_type = A::C<2ul>*]'
34:51: required from here
/usr/include/boost/variant/variant.hpp:1048:32: error: cannot convert 'A::C<1ul>*' to 'boost::detail::variant::invoke_visitor<const A::C<2ul> >::result_type {aka A::C<2ul>*}' in return
return visitor_(operand);
It compiles and works fine if I remove C<1> * from the boost::variant declaration.
Any suggestions would be highly appreciated.
All visitor functions must follow the scheme defined by base class: boost::static_visitor<C<dim> *>.
That means return value of operator() must be always C<dim> * not C<t>* - see:
template<size_t dim>
struct C : boost::static_visitor<C<dim> *> {
template <size_t t>
C<dim> * operator()(C<t> *s) const {
// ^^^ - not t, must be as static_visitor parameter few lines above
std::cout<<s->x<<std::endl;
return s; // of course this part will have problems to compile
// e.g. pointers to C<2> and C<1> are not convertible
}
As I put in comments in right of return s- this does not compile - because compiler cannot covert C<1> to C<2>.
What you might do to solve this, is to introduce base class - like below:
struct CBase {
int x;
};
template<size_t dim>
struct C : CBase, boost::static_visitor<CBase*> {
C() : CBase{dim} {}
template <size_t t>
CBase* operator()(C<t> *s) const {
std::cout<<s->x<<std::endl;
return s;
}
I'm writing a small C++ module for Python. In this module I set connection to different databases. Connection to one of those databases is set like so:
std::unique_ptr<R::Connection> conn = R::connect("localhost", 28015);
After I set connection, I want to return this connection variable. The way I do it is using vector and variant (since I may return multiple things in a vector - database connection, some extra parameters etc).
This is how I define variant and vector types:
typedef variant<std::unique_ptr<R::Connection>,....connections to other databases> VariantData;
typedef std::vector<VariantData> vector;
And, finally, this is how I return a vector right after I set connection:
return vector{conn, ""};
As a result, I get a long list of errors. However, this trick works well with other clients which set connections to other databases and do not use unique_ptr. So, I think I need something like casting std::unique_ptr<R::Connection> to Connection * or something like that, to be able to use conn variable like a general pointer.
EDIT
With these snippets of code:
typedef variant<R::Connection * ,....connections to other databases> VariantData;
typedef std::vector<VariantData> vector;
... function body
... code which does not matter
std::unique_ptr<R::Connection> conn = R::connect("localhost", 28015);
return vector{move(conn),""};
And this is the error messages I get:
n file included from /usr/include/boost/variant.hpp:17:0,
from corm.cpp:4:
/usr/include/boost/variant/variant.hpp: In instantiation of ‘typename boost::enable_if<boost::is_rvalue_reference<T&&> >::type boost::variant<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19>::convert_construct(T&&, int, mpl_::false_) [with T = std::unique_ptr<RethinkDB::Connection>; T0_ = mysqlpp::Connection*; T1 = mongo::DBClientBase*; T2 = pqxx::basic_connection<pqxx::connect_direct>*; T3 = sqlite3**; T4 = IBPP::Ptr<IBPP::IDatabase>; T5 = RethinkDB::Connection*; T6 = const char*; T7 = boost::detail::variant::void_; T8 = boost::detail::variant::void_; T9 = boost::detail::variant::void_; T10 = boost::detail::variant::void_; T11 = boost::detail::variant::void_; T12 = boost::detail::variant::void_; T13 = boost::detail::variant::void_; T14 = boost::detail::variant::void_; T15 = boost::detail::variant::void_; T16 = boost::detail::variant::void_; T17 = boost::detail::variant::void_; T18 = boost::detail::variant::void_; T19 = boost::detail::variant::void_; typename boost::enable_if<boost::is_rvalue_reference<T&&> >::type = void; mpl_::false_ = mpl_::bool_<false>]’:
/usr/include/boost/variant/variant.hpp:1789:62: required from ‘boost::variant<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19>::variant(T&&, typename boost::enable_if<boost::is_rvalue_reference<T&&> >::type*, typename boost::disable_if<boost::is_const<FunctionObj> >::type*) [with T = std::unique_ptr<RethinkDB::Connection>; T0_ = mysqlpp::Connection*; T1 = mongo::DBClientBase*; T2 = pqxx::basic_connection<pqxx::connect_direct>*; T3 = sqlite3**; T4 = IBPP::Ptr<IBPP::IDatabase>; T5 = RethinkDB::Connection*; T6 = const char*; T7 = boost::detail::variant::void_; T8 = boost::detail::variant::void_; T9 = boost::detail::variant::void_; T10 = boost::detail::variant::void_; T11 = boost::detail::variant::void_; T12 = boost::detail::variant::void_; T13 = boost::detail::variant::void_; T14 = boost::detail::variant::void_; T15 = boost::detail::variant::void_; T16 = boost::detail::variant::void_; T17 = boost::detail::variant::void_; T18 = boost::detail::variant::void_; T19 = boost::detail::variant::void_; typename boost::enable_if<boost::is_rvalue_reference<T&&> >::type = void; typename boost::disable_if<boost::is_const<FunctionObj> >::type = void]’
corm.cpp:94:39: required from here
/usr/include/boost/variant/variant.hpp:1615:17: error: no matching function for call to ‘boost::variant<mysqlpp::Connection*, mongo::DBClientBase*, pqxx::basic_connection<pqxx::connect_direct>*, sqlite3**, IBPP::Ptr<IBPP::IDatabase>, RethinkDB::Connection*, const char*>::initializer::initialize(void*, boost::remove_reference<std::unique_ptr<RethinkDB::Connection>&>::type)’
)
^
/usr/include/boost/variant/variant.hpp:1615:17: note: candidates are:
In file included from /usr/include/boost/variant/variant.hpp:33:0,
from /usr/include/boost/variant.hpp:17,
from corm.cpp:4:
/usr/include/boost/variant/detail/initializer.hpp:104:24: note: static int boost::detail::variant::make_initializer_node::apply<BaseIndexPair, Iterator>::initializer_node::initialize(void*, boost::detail::variant::make_initializer_node::apply<BaseIndexPair, Iterator>::initializer_node::param_T) [with BaseIndexPair = boost::mpl::pair<boost::detail::variant::make_initializer_node::apply<boost::mpl::pair<boost::detail::variant::make_initializer_node::apply<boost::mpl::pair<boost::detail::variant::make_initializer_node::apply<boost::mpl::pair<boost::detail::variant::make_initializer_node::apply<boost::mpl::pair<boost::detail::variant::make_initializer_node::apply<boost::mpl::pair<boost::detail::variant::make_initializer_node::apply<boost::mpl::pair<boost::detail::variant::initializer_root, mpl_::int_<0> >,
>::initializer_node::param_T {aka RethinkDB::Connection* const&}’
Makefile:45: recipe for target 'corm.o' failed
make: *** [corm.o] Error 1
EDIT
This is the code (minimized)
#include <boost/python.hpp>
#include <boost/python/suite/indexing/vector_indexing_suite.hpp>
#include <boost/variant.hpp>
#include <vector>
#include <memory>
#include <rethinkdb.h>
using namespace boost;
using namespace boost::python;
namespace Ret = RethinkDB;
typedef variant<Ret::Connection *, const char*> VariantData;
typedef std::vector<VariantData> vector;
class ORM{
private:
int idx;
public:
ORM(int _idx){
this->idx = _idx;
}
vector Connect(){
if(this->idx == 8){
std::unique_ptr<Ret::Connection> conn = Ret::connect(this->host, this->port);
return vector{std::move(conn), ""};
}
}
};
struct variant_to_object:static_visitor<PyObject*>{
static result_type convert(VariantData const& v){
return apply_visitor(variant_to_object(), v);
}
template<typename T>
result_type operator () (T const& v) const{
return incref(object(v).ptr());
}
};
BOOST_PYTHON_MODULE(corm){
class_<vector>("vector").def(vector_indexing_suite<vector, true>());
to_python_converter<VariantData, variant_to_object>();
implicitly_convertible<Ret::Connection *, VariantData>();
implicitly_convertible<const char*, VariantData>();
class_<ORM>("ORM",
init<int>())
.def("Connect", &ORM::Connect);
}
Client for rethinkdb is taken from here.
boost::make_recursive_variant is intended to make variants which are recursive, without requiring the creation of an intermediate type by using the tag type boost::recursive_variant_. For std::vector<recursive_variant_> this appears to work fine, however for a std::tuple<int, recursive_variant_> it fails.
Example:
#include <type_traits>
#include <tuple>
#include <vector>
#include <boost/variant.hpp>
using std::cout;
using std::vector;
using std::tuple;
using boost::variant;
using boost::static_visitor;
using boost::apply_visitor;
using boost::make_recursive_variant;
using boost::recursive_variant_;
using A = typename make_recursive_variant<
int,
vector<recursive_variant_>
>::type;
using B = vector<A>;
using C = typename make_recursive_variant<
int,
tuple<int, recursive_variant_>
>::type;
using D = tuple<int, C>;
int main(int, char**)
{
A a = 0;
B b{1, 2};
a = b;
C c = 0;
D d{0, 1};
//c = d;
}
If the last line is uncommented, the program no longer compiles. Is this a usage error (and if yes, how so?), or is it bug or limitation in boost::tuple?
Error message (on mingw-w64 with gcc 4.8.1):
In file included from D:/libs/3rdparty-prebuild-vc11-win64/vc11/win64/boost-1_54_0-vc11-win64/include/boost-1_54/boost/variant.hpp:17:0,
from D:\projects\test\main.cpp:4:
D:/libs/3rdparty-prebuild-vc11-win64/vc11/win64/boost-1_54_0-vc11-win64/include/boost-1_54/boost/variant/variant.hpp: In instantiation of 'void boost::variant<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19>::convert_construct(T&, int, mpl_::false_) [with T = const std::tuple<int, boost::variant<boost::detail::variant::recursive_flag<int>, std::tuple<int, boost::recursive_variant_>, 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_> >; T0_ = boost::detail::variant::recursive_flag<int>; T1 = std::tuple<int, boost::recursive_variant_>; T2 = boost::detail::variant::void_; T3 = boost::detail::variant::void_; T4 = boost::detail::variant::void_; T5 = boost::detail::variant::void_; T6 = boost::detail::variant::void_; T7 = boost::detail::variant::void_; T8 = boost::detail::variant::void_; T9 = boost::detail::variant::void_; T10 = boost::detail::variant::void_; T11 = boost::detail::variant::void_; T12 = boost::detail::variant::void_; T13 = boost::detail::variant::void_; T14 = boost::detail::variant::void_; T15 = boost::detail::variant::void_; T16 = boost::detail::variant::void_; T17 = boost::detail::variant::void_; T18 = boost::detail::variant::void_; T19 = boost::detail::variant::void_; mpl_::false_ = mpl_::bool_<false>]':
D:/libs/3rdparty-prebuild-vc11-win64/vc11/win64/boost-1_54_0-vc11-win64/include/boost-1_54/boost/variant/variant.hpp:1703:38: required from 'boost::variant<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19>::variant(const T&) [with T = std::tuple<int, boost::variant<boost::detail::variant::recursive_flag<int>, std::tuple<int, boost::recursive_variant_>, 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_> >; T0_ = boost::detail::variant::recursive_flag<int>; T1 = std::tuple<int, boost::recursive_variant_>; T2 = boost::detail::variant::void_; T3 = boost::detail::variant::void_; T4 = boost::detail::variant::void_; T5 = boost::detail::variant::void_; T6 = boost::detail::variant::void_; T7 = boost::detail::variant::void_; T8 = boost::detail::variant::void_; T9 = boost::detail::variant::void_; T10 = boost::detail::variant::void_; T11 = boost::detail::variant::void_; T12 = boost::detail::variant::void_; T13 = boost::detail::variant::void_; T14 = boost::detail::variant::void_; T15 = boost::detail::variant::void_; T16 = boost::detail::variant::void_; T17 = boost::detail::variant::void_; T18 = boost::detail::variant::void_; T19 = boost::detail::variant::void_]'
D:/libs/3rdparty-prebuild-vc11-win64/vc11/win64/boost-1_54_0-vc11-win64/include/boost-1_54/boost/variant/variant.hpp:2129:29: required from 'void boost::variant<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19>::assign(const T&) [with T = std::tuple<int, boost::variant<boost::detail::variant::recursive_flag<int>, std::tuple<int, boost::recursive_variant_>, 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_> >; T0_ = boost::detail::variant::recursive_flag<int>; T1 = std::tuple<int, boost::recursive_variant_>; T2 = boost::detail::variant::void_; T3 = boost::detail::variant::void_; T4 = boost::detail::variant::void_; T5 = boost::detail::variant::void_; T6 = boost::detail::variant::void_; T7 = boost::detail::variant::void_; T8 = boost::detail::variant::void_; T9 = boost::detail::variant::void_; T10 = boost::detail::variant::void_; T11 = boost::detail::variant::void_; T12 = boost::detail::variant::void_; T13 = boost::detail::variant::void_; T14 = boost::detail::variant::void_; T15 = boost::detail::variant::void_; T16 = boost::detail::variant::void_; T17 = boost::detail::variant::void_; T18 = boost::detail::variant::void_; T19 = boost::detail::variant::void_]'
D:/libs/3rdparty-prebuild-vc11-win64/vc11/win64/boost-1_54_0-vc11-win64/include/boost-1_54/boost/variant/variant.hpp:2168:19: required from 'boost::variant<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19>& boost::variant<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19>::operator=(const T&) [with T = std::tuple<int, boost::variant<boost::detail::variant::recursive_flag<int>, std::tuple<int, boost::recursive_variant_>, 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_> >; T0_ = boost::detail::variant::recursive_flag<int>; T1 = std::tuple<int, boost::recursive_variant_>; T2 = boost::detail::variant::void_; T3 = boost::detail::variant::void_; T4 = boost::detail::variant::void_; T5 = boost::detail::variant::void_; T6 = boost::detail::variant::void_; T7 = boost::detail::variant::void_; T8 = boost::detail::variant::void_; T9 = boost::detail::variant::void_; T10 = boost::detail::variant::void_; T11 = boost::detail::variant::void_; T12 = boost::detail::variant::void_; T13 = boost::detail::variant::void_; T14 = boost::detail::variant::void_; T15 = boost::detail::variant::void_; T16 = boost::detail::variant::void_; T17 = boost::detail::variant::void_; T18 = boost::detail::variant::void_; T19 = boost::detail::variant::void_]'
D:\projects\test\main.cpp:37:4: required from here
D:/libs/3rdparty-prebuild-vc11-win64/vc11/win64/boost-1_54_0-vc11-win64/include/boost-1_54/boost/variant/variant.hpp:1557:17: error: no matching function for call to 'boost::variant<boost::detail::variant::recursive_flag<int>, std::tuple<int, boost::recursive_variant_>, 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_>::initializer::initialize(void*, const std::tuple<int, boost::variant<boost::detail::variant::recursive_flag<int>, std::tuple<int, boost::recursive_variant_>, 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_> >&)'
)
^
D:/libs/3rdparty-prebuild-vc11-win64/vc11/win64/boost-1_54_0-vc11-win64/include/boost-1_54/boost/variant/variant.hpp:1557:17: note: candidates are:
In file included from D:/libs/3rdparty-prebuild-vc11-win64/vc11/win64/boost-1_54_0-vc11-win64/include/boost-1_54/boost/variant/variant.hpp:31:0,
from D:/libs/3rdparty-prebuild-vc11-win64/vc11/win64/boost-1_54_0-vc11-win64/include/boost-1_54/boost/variant.hpp:17,
from D:\projects\test\main.cpp:4:
D:/libs/3rdparty-prebuild-vc11-win64/vc11/win64/boost-1_54_0-vc11-win64/include/boost-1_54/boost/variant/detail/initializer.hpp:104:24: note: static int boost::detail::variant::make_initializer_node::apply<BaseIndexPair, Iterator>::initializer_node::initialize(void*, boost::detail::variant::make_initializer_node::apply<BaseIndexPair, Iterator>::initializer_node::param_T) [with BaseIndexPair = boost::mpl::pair<boost::detail::variant::make_initializer_node::apply<boost::mpl::pair<boost::detail::variant::initializer_root, mpl_::int_<0> >, boost::mpl::l_iter<boost::mpl::l_item<mpl_::long_<2l>, int, boost::mpl::l_item<mpl_::long_<1l>, std::tuple<int, boost::recursive_variant_>, boost::mpl::l_end> > > >::initializer_node, mpl_::int_<1> >; Iterator = boost::mpl::l_iter<boost::mpl::l_item<mpl_::long_<1l>, std::tuple<int, boost::recursive_variant_>, boost::mpl::l_end> >; boost::detail::variant::make_initializer_node::apply<BaseIndexPair, Iterator>::initializer_node::param_T = const std::tuple<int, boost::recursive_variant_>&]
static int initialize(void* dest, param_T operand)
^
D:/libs/3rdparty-prebuild-vc11-win64/vc11/win64/boost-1_54_0-vc11-win64/include/boost-1_54/boost/variant/detail/initializer.hpp:104:24: note: no known conversion for argument 2 from 'const std::tuple<int, boost::variant<boost::detail::variant::recursive_flag<int>, std::tuple<int, boost::recursive_variant_>, 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_> >' to 'boost::detail::variant::make_initializer_node::apply<boost::mpl::pair<boost::detail::variant::make_initializer_node::apply<boost::mpl::pair<boost::detail::variant::initializer_root, mpl_::int_<0> >, boost::mpl::l_iter<boost::mpl::l_item<mpl_::long_<2l>, int, boost::mpl::l_item<mpl_::long_<1l>, std::tuple<int, boost::recursive_variant_>, boost::mpl::l_end> > > >::initializer_node, mpl_::int_<1> >, boost::mpl::l_iter<boost::mpl::l_item<mpl_::long_<1l>, std::tuple<int, boost::recursive_variant_>, boost::mpl::l_end> > >::initializer_node::param_T {aka const std::tuple<int, boost::recursive_variant_>&}'
D:/libs/3rdparty-prebuild-vc11-win64/vc11/win64/boost-1_54_0-vc11-win64/include/boost-1_54/boost/variant/detail/initializer.hpp:115:24: note: static int boost::detail::variant::make_initializer_node::apply<BaseIndexPair, Iterator>::initializer_node::initialize(void*, boost::detail::variant::make_initializer_node::apply<BaseIndexPair, Iterator>::initializer_node::param2_T) [with BaseIndexPair = boost::mpl::pair<boost::detail::variant::make_initializer_node::apply<boost::mpl::pair<boost::detail::variant::initializer_root, mpl_::int_<0> >, boost::mpl::l_iter<boost::mpl::l_item<mpl_::long_<2l>, int, boost::mpl::l_item<mpl_::long_<1l>, std::tuple<int, boost::recursive_variant_>, boost::mpl::l_end> > > >::initializer_node, mpl_::int_<1> >; Iterator = boost::mpl::l_iter<boost::mpl::l_item<mpl_::long_<1l>, std::tuple<int, boost::recursive_variant_>, boost::mpl::l_end> >; boost::detail::variant::make_initializer_node::apply<BaseIndexPair, Iterator>::initializer_node::param2_T = std::tuple<int, boost::recursive_variant_>&&]
static int initialize(void* dest, param2_T operand)
^
D:/libs/3rdparty-prebuild-vc11-win64/vc11/win64/boost-1_54_0-vc11-win64/include/boost-1_54/boost/variant/detail/initializer.hpp:115:24: note: no known conversion for argument 2 from 'const std::tuple<int, boost::variant<boost::detail::variant::recursive_flag<int>, std::tuple<int, boost::recursive_variant_>, 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_> >' to 'boost::detail::variant::make_initializer_node::apply<boost::mpl::pair<boost::detail::variant::make_initializer_node::apply<boost::mpl::pair<boost::detail::variant::initializer_root, mpl_::int_<0> >, boost::mpl::l_iter<boost::mpl::l_item<mpl_::long_<2l>, int, boost::mpl::l_item<mpl_::long_<1l>, std::tuple<int, boost::recursive_variant_>, boost::mpl::l_end> > > >::initializer_node, mpl_::int_<1> >, boost::mpl::l_iter<boost::mpl::l_item<mpl_::long_<1l>, std::tuple<int, boost::recursive_variant_>, boost::mpl::l_end> > >::initializer_node::param2_T {aka std::tuple<int, boost::recursive_variant_>&&}'
D:/libs/3rdparty-prebuild-vc11-win64/vc11/win64/boost-1_54_0-vc11-win64/include/boost-1_54/boost/variant/detail/initializer.hpp:149:17: note: static void boost::detail::variant::initializer_root::initialize()
static void initialize();
^
D:/libs/3rdparty-prebuild-vc11-win64/vc11/win64/boost-1_54_0-vc11-win64/include/boost-1_54/boost/variant/detail/initializer.hpp:149:17: note: candidate expects 0 arguments, 2 provided
D:/libs/3rdparty-prebuild-vc11-win64/vc11/win64/boost-1_54_0-vc11-win64/include/boost-1_54/boost/variant/detail/initializer.hpp:115:24: note: static int boost::detail::variant::make_initializer_node::apply<BaseIndexPair, Iterator>::initializer_node::initialize(void*, boost::detail::variant::make_initializer_node::apply<BaseIndexPair, Iterator>::initializer_node::param2_T) [with BaseIndexPair = boost::mpl::pair<boost::detail::variant::initializer_root, mpl_::int_<0> >; Iterator = boost::mpl::l_iter<boost::mpl::l_item<mpl_::long_<2l>, int, boost::mpl::l_item<mpl_::long_<1l>, std::tuple<int, boost::recursive_variant_>, boost::mpl::l_end> > >; boost::detail::variant::make_initializer_node::apply<BaseIndexPair, Iterator>::initializer_node::param2_T = int&&]
static int initialize(void* dest, param2_T operand)
^
D:/libs/3rdparty-prebuild-vc11-win64/vc11/win64/boost-1_54_0-vc11-win64/include/boost-1_54/boost/variant/detail/initializer.hpp:115:24: note: no known conversion for argument 2 from 'const std::tuple<int, boost::variant<boost::detail::variant::recursive_flag<int>, std::tuple<int, boost::recursive_variant_>, 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_> >' to 'boost::detail::variant::make_initializer_node::apply<boost::mpl::pair<boost::detail::variant::initializer_root, mpl_::int_<0> >, boost::mpl::l_iter<boost::mpl::l_item<mpl_::long_<2l>, int, boost::mpl::l_item<mpl_::long_<1l>, std::tuple<int, boost::recursive_variant_>, boost::mpl::l_end> > > >::initializer_node::param2_T {aka int&&}'
D:/libs/3rdparty-prebuild-vc11-win64/vc11/win64/boost-1_54_0-vc11-win64/include/boost-1_54/boost/variant/detail/initializer.hpp:104:24: note: static int boost::detail::variant::make_initializer_node::apply<BaseIndexPair, Iterator>::initializer_node::initialize(void*, boost::detail::variant::make_initializer_node::apply<BaseIndexPair, Iterator>::initializer_node::param_T) [with BaseIndexPair = boost::mpl::pair<boost::detail::variant::initializer_root, mpl_::int_<0> >; Iterator = boost::mpl::l_iter<boost::mpl::l_item<mpl_::long_<2l>, int, boost::mpl::l_item<mpl_::long_<1l>, std::tuple<int, boost::recursive_variant_>, boost::mpl::l_end> > >; boost::detail::variant::make_initializer_node::apply<BaseIndexPair, Iterator>::initializer_node::param_T = const int&]
static int initialize(void* dest, param_T operand)
^
D:/libs/3rdparty-prebuild-vc11-win64/vc11/win64/boost-1_54_0-vc11-win64/include/boost-1_54/boost/variant/detail/initializer.hpp:104:24: note: no known conversion for argument 2 from 'const std::tuple<int, boost::variant<boost::detail::variant::recursive_flag<int>, std::tuple<int, boost::recursive_variant_>, 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_> >' to 'boost::detail::variant::make_initializer_node::apply<boost::mpl::pair<boost::detail::variant::initializer_root, mpl_::int_<0> >, boost::mpl::l_iter<boost::mpl::l_item<mpl_::long_<2l>, int, boost::mpl::l_item<mpl_::long_<1l>, std::tuple<int, boost::recursive_variant_>, boost::mpl::l_end> > > >::initializer_node::param_T {aka const int&}'
The problem is that make_recursive_variant isn't aware of variadic templates, so it doesn't know to expand recursive_variant_ within std::tuple<..., recursive_variant_>.
You can test this by changing std::tuple to std::pair (a fixed-adic template) and observing that that works fine.
As a workaround, you can teach Boost.Variant how to expand within variadic templates with the following snippet (place at the top level of your source file):
namespace boost { namespace detail { namespace variant {
template<template<typename...> class F, typename... Ts, typename Dest, typename Source>
struct substitute<
F<Ts...>
, Dest
, Source
BOOST_MPL_AUX_LAMBDA_ARITY_PARAM(mpl::int_<-1>)
>
{
typedef F<typename substitute<
Ts, Dest, Source
>::type...> type;
};
}}} // namespace boost::detail::variant
Edit: I've put in a pull request: https://github.com/boostorg/variant/pull/2
I have tried for hours to code a class deriving from boost::variant. But I do not understand what is the problem (I do not understand what the compilation error means).
What are the rules to implement a clean boost::variant derived-class?
#include <boost/variant.hpp>
class MyVariant : public boost::variant<char,bool>
{
public:
MyVariant () : boost::variant<char,bool>( ) {}
template <typename T>
MyVariant( T& v) : boost::variant<char,bool>(v) {}
template <typename T>
MyVariant(const T& v) : boost::variant<char,bool>(v) {}
};
int main ()
{
MyVariant a;
MyVariant b = a; //compilation error
// MyVariant c = MyVariant();
// MyVariant d (true);
// MyVariant e ('E');
}
Why do I want to use inheritance? (EDIT to give more details to #zaufi)
I want an empty state
I want to accept const char* as string
I want to accept int as long
I want to give enum types
For instance, in pseudo C++ code, my hopes:
class MyVariant : public boost::variant<char,bool,long,std::string>
{
typedef boost::variant<char,bool,long,std::string> super;
public:
// I know here I should specialize templeted constructors
// but I is more clear like that, isn't it?
MyVariant() : super('e') {} //empty -> char
MyVariant(char c) : super(std::string(1,c)){} //char -> string
MyVariant(const char* s) : super(std::string(s) ) {} //char* -> string
MyVariant(int v) : super(long (v) ) {} //TODO boundaries
/* other constructors ... */
enum Type
{
NONE, //my empty state = char type
BOOL,
LONG,
STRING
};
Type type() const { return (Type) which(); }
};
The basic snippet code (on top of the question) has been tested on different platforms
boost v1.33 + GCC 4.1 (Linux)
boost v1.52 + GCC 4.7 (MinGW)
boost v1.52 + Visual C++ 2010 (v10)
Below my errors for the two versions of GCC
(I can remove one of the both if it bothers someone...)
$ g++ --version
g++ (GCC) 4.1.2 20080704 (Red Hat 4.1.2-52)
Copyright (C) 2006 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
$ g++ myVariant.cpp
/usr/include/boost/variant/variant.hpp: In constructor 'boost::variant<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19>::variant(T&) [with T = MyVariant, T0_ = char, T1 = bool, T2 = boost::detail::variant::void_, T3 = boost::detail::variant::void_, T4 = boost::detail::variant::void_, T5 = boost::detail::variant::void_, T6 = boost::detail::variant::void_, T7 = boost::detail::variant::void_, T8 = boost::detail::variant::void_, T9 = boost::detail::variant::void_, T10 = boost::detail::variant::void_, T11 = boost::detail::variant::void_, T12 = boost::detail::variant::void_, T13 = boost::detail::variant::void_, T14 = boost::detail::variant::void_, T15 = boost::detail::variant::void_, T16 = boost::detail::variant::void_, T17 = boost::detail::variant::void_, T18 = boost::detail::variant::void_, T19 = boost::detail::variant::void_]':
myVariant.cpp:10: instantiated from 'MyVariant::MyVariant(T&) [with T = MyVariant]'
myVariant.cpp:19: instantiated from here
/usr/include/boost/variant/variant.hpp:1348: error: call of overloaded 'convert_construct(MyVariant&, long int)' is ambiguous
/usr/include/boost/variant/variant.hpp:1262: note: candidates are: void boost::variant<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19>::convert_construct(T&, int, mpl_::false_) [with T = MyVariant, T0_ = char, T1 = bool, T2 = boost::detail::variant::void_, T3 = boost::detail::variant::void_, T4 = boost::detail::variant::void_, T5 = boost::detail::variant::void_, T6 = boost::detail::variant::void_, T7 = boost::detail::variant::void_, T8 = boost::detail::variant::void_, T9 = boost::detail::variant::void_, T10 = boost::detail::variant::void_, T11 = boost::detail::variant::void_, T12 = boost::detail::variant::void_, T13 = boost::detail::variant::void_, T14 = boost::detail::variant::void_, T15 = boost::detail::variant::void_, T16 = boost::detail::variant::void_, T17 = boost::detail::variant::void_, T18 = boost::detail::variant::void_, T19 = boost::detail::variant::void_]
/usr/include/boost/variant/variant.hpp:1321: note: void boost::variant<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19>::convert_construct(boost::variant<U0, U1, U2, U3, U4, U5, U6, U7, U8, U9, U10, U11, U12, U13, U14, U15, U16, U17, U18, U19>&, long int) [with U0 = char, U1 = bool, U2 = boost::detail::variant::void_, U3 = boost::detail::variant::void_, U4 = boost::detail::variant::void_, U5 = boost::detail::variant::void_, U6 = boost::detail::variant::void_, U7 = boost::detail::variant::void_, U8 = boost::detail::variant::void_, U9 = boost::detail::variant::void_, U10 = boost::detail::variant::void_, U11 = boost::detail::variant::void_, U12 = boost::detail::variant::void_, U13 = boost::detail::variant::void_, U14 = boost::detail::variant::void_, U15 = boost::detail::variant::void_, U16 = boost::detail::variant::void_, U17 = boost::detail::variant::void_, U18 = boost::detail::variant::void_, U19 = boost::detail::variant::void_, T0_ = char, T1 = bool, T2 = boost::detail::variant::void_, T3 = boost::detail::variant::void_, T4 = boost::detail::variant::void_, T5 = boost::detail::variant::void_, T6 = boost::detail::variant::void_, T7 = boost::detail::variant::void_, T8 = boost::detail::variant::void_, T9 = boost::detail::variant::void_, T10 = boost::detail::variant::void_, T11 = boost::detail::variant::void_, T12 = boost::detail::variant::void_, T13 = boost::detail::variant::void_, T14 = boost::detail::variant::void_, T15 = boost::detail::variant::void_, T16 = boost::detail::variant::void_, T17 = boost::detail::variant::void_, T18 = boost::detail::variant::void_, T19 = boost::detail::variant::void_]
/usr/include/boost/variant/variant.hpp:1330: note: void boost::variant<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19>::convert_construct(const boost::variant<U0, U1, U2, U3, U4, U5, U6, U7, U8, U9, U10, U11, U12, U13, U14, U15, U16, U17, U18, U19>&, long int) [with U0 = char, U1 = bool, U2 = boost::detail::variant::void_, U3 = boost::detail::variant::void_, U4 = boost::detail::variant::void_, U5 = boost::detail::variant::void_, U6 = boost::detail::variant::void_, U7 = boost::detail::variant::void_, U8 = boost::detail::variant::void_, U9 = boost::detail::variant::void_, U10 = boost::detail::variant::void_, U11 = boost::detail::variant::void_, U12 = boost::detail::variant::void_, U13 = boost::detail::variant::void_, U14 = boost::detail::variant::void_, U15 = boost::detail::variant::void_, U16 = boost::detail::variant::void_, U17 = boost::detail::variant::void_, U18 = boost::detail::variant::void_, U19 = boost::detail::variant::void_, T0_ = char, T1 = bool, T2 = boost::detail::variant::void_, T3 = boost::detail::variant::void_, T4 = boost::detail::variant::void_, T5 = boost::detail::variant::void_, T6 = boost::detail::variant::void_, T7 = boost::detail::variant::void_, T8 = boost::detail::variant::void_, T9 = boost::detail::variant::void_, T10 = boost::detail::variant::void_, T11 = boost::detail::variant::void_, T12 = boost::detail::variant::void_, T13 = boost::detail::variant::void_, T14 = boost::detail::variant::void_, T15 = boost::detail::variant::void_, T16 = boost::detail::variant::void_, T17 = boost::detail::variant::void_, T18 = boost::detail::variant::void_, T19 = boost::detail::variant::void_]
$ g++ --version
g++.exe (GCC) 4.7.2
Copyright (C) 2012 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
$ g++ myVariant.cpp -I /c/.../include/
In file included from c:/.../include/boost/variant.hpp:17:0,
from myVariant.cpp:1:
c:/.../include/boost/variant/variant.hpp: In instantiation of 'boost::variant<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19>::variant(T&) [with T = MyVariant; T0_ = char; T1 = bool; T2 = boost::detail::variant::void_; T3 = boost::detail::variant::void_; T4 = boost::detail::variant::void_; T5 = boost::detail::variant::void_; T6 = boost::detail::variant::void_; T7 = boost::detail::variant::void_; T8 = boost::detail::variant::void_; T9 = boost::detail::variant::void_; T10 = boost::detail::variant::void_; T11 = boost::detail::variant::void_; T12 = boost::detail::variant::void_; T13 = boost::detail::variant::void_; T14 = boost::detail::variant::void_; T15 = boost::detail::variant::void_; T16 = boost::detail::variant::void_; T17 = boost::detail::variant::void_; T18 = boost::detail::variant::void_; T19 = boost::detail::variant::void_]':
myVariant.cpp:9:66: required from 'MyVariant::MyVariant(T&) [with T = MyVariant]'
myVariant.cpp:18:25: required from here
c:/.../include/boost/variant/variant.hpp:1406:9: error: call of overloaded convert_construct(MyVariant&, long int)' is ambiguous
c:/.../include/boost/variant/variant.hpp:1406:9: note: candidates are:
c:/.../include/boost/variant/variant.hpp:1316:10: note: void boost::variant<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19>::convert_construct(T&, int, mpl_::false_) [with T = MyVariant; T0_ = char; T1 = bool; T2 = boost::detail::variant::void_; T3 = boost::detail::variant::void_; T4 = boost::detail::variant::void_; T5 = boost::detail::variant::void_; T6 = boost::detail::variant::void_; T7 = boost::detail::variant::void_; T8 = boost::detail::variant::void_; T9 = boost::detail::variant::void_; T10 = boost::detail::variant::void_; T11 = boost::detail::variant::void_; T12 = boost::detail::variant::void_; T13 = boost::detail::variant::void_; T14 = boost::detail::variant::void_; T15 = boost::detail::variant::void_; T16 = boost::detail::variant::void_; T17 = boost::detail::variant::void_; T18 = boost::detail::variant::void_; T19 = boost::detail::variant::void_; mpl_::false_ = mpl_::bool_<false>]
c:/.../include/boost/variant/variant.hpp:1376:10: note: void boost::variant<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19>::convert_construct(boost::variant<U0, U1, U2, U3, U4, U5, U6, U7, U8, U9, U10, U11, U12, U13, U14, U15, U16, U17, U18, U19>&, long int) [with U0 = char; U1 = bool; U2 = boost::detail::variant::void_; U3 = boost::detail::variant::void_; U4 = boost::detail::variant::void_; U5 = boost::detail::variant::void_; U6 = boost::detail::variant::void_; U7 = boost::detail::variant::void_; U8 = boost::detail::variant::void_; U9 = boost::detail::variant::void_; U10 = boost::detail::variant::void_; U11 = boost::detail::variant::void_; U12 = boost::detail::variant::void_; U13 = boost::detail::variant::void_; U14 = boost::detail::variant::void_; U15 = boost::detail::variant::void_; U16 = boost::detail::variant::void_; U17 = boost::detail::variant::void_; U18 = boost::detail::variant::void_; U19 = boost::detail::variant::void_; T0_ = char; T1 = bool; T2 = boost::detail::variant::void_; T3 = boost::detail::variant::void_; T4 = boost::detail::variant::void_; T5 = boost::detail::variant::void_; T6 = boost::detail::variant::void_; T7 = boost::detail::variant::void_; T8 = boost::detail::variant::void_; T9 = boost::detail::variant::void_; T10 = boost::detail::variant::void_; T11 = boost::detail::variant::void_; T12 = boost::detail::variant::void_; T13 = boost::detail::variant::void_; T14 = boost::detail::variant::void_; T15 = boost::detail::variant::void_; T16 = boost::detail::variant::void_; T17 = boost::detail::variant::void_; T18 = boost::detail::variant::void_; T19 = boost::detail::variant::void_]
c:/.../include/boost/variant/variant.hpp:1385:10: note: void boost::variant<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19>::convert_construct(const boost::variant<U0, U1, U2, U3, U4, U5, U6, U7, U8, U9, U10, U11, U12, U13, U14, U15, U16, U17, U18, U19>&, long int) [with U0 = char; U1 = bool; U2 = boost::detail::variant::void_; U3 = boost::detail::variant::void_; U4 = boost::detail::variant::void_; U5 = boost::detail::variant::void_; U6 = boost::detail::variant::void_; U7 = boost::detail::variant::void_; U8 = boost::detail::variant::void_; U9 = boost::detail::variant::void_; U10 = boost::detail::variant::void_; U11 = boost::detail::variant::void_; U12 = boost::detail::variant::void_; U13 = boost::detail::variant::void_; U14 = boost::detail::variant::void_; U15 = boost::detail::variant::void_; U16 = boost::detail::variant::void_; U17 = boost::detail::variant::void_; U18 = boost::detail::variant::void_; U19 = boost::detail::variant::void_; T0_ = char; T1 = bool; T2 = boost::detail::variant::void_; T3 = boost::detail::variant::void_; T4 = boost::detail::variant::void_; T5 = boost::detail::variant::void_; T6 = boost::detail::variant::void_; T7 = boost::detail::variant::void_; T8 = boost::detail::variant::void_; T9 = boost::detail::variant::void_; T10 = boost::detail::variant::void_; T11 = boost::detail::variant::void_; T12 = boost::detail::variant::void_; T13 = boost::detail::variant::void_; T14 = boost::detail::variant::void_; T15 = boost::detail::variant::void_; T16 = boost::detail::variant::void_; T17 = boost::detail::variant::void_; T18 = boost::detail::variant::void_; T19 = boost::detail::variant::void_]
The accepted answer and the other answers do not answer the question. There are good reasons to derive from boost::variant.
you want to add methods into the variant, so that it behaves more polymorphic
you want to keep using boost::apply_visitor(visitor(), variant) without jumping through hoops
Here is a working example of a type MyVariant inheriting from boost::variant. The code requires C++11 to inherit the (complex) constructors of boost::variant.
Edit: Operators such as equal comparison implemented in boost::variant do not automatically work for the derived class. This is a (unintended) consequence of how boost::variant is implemented, it explicitly prevents comparisons to "foreign" types using templates. Operators can be enabled with explicit overloads, as shown in the example.
#include<iostream>
#include<boost/variant.hpp>
struct type_size_visitor : public boost::static_visitor<unsigned> {
template <typename T>
unsigned operator()(const T&) const { return sizeof(T); }
};
template <typename... Types>
class MyVariant : public boost::variant<Types...>
{
using base_type = boost::variant<Types...>;
public:
// inherit constructors
using base_type::base_type;
// add a new method
unsigned type_size() { return boost::apply_visitor(type_size_visitor(), *this); }
/* Inheriting operators from boost::variant does not
work as it normally would. We have to add explicit
overloads for the operators we want to use.
*/
bool operator==(const MyVariant& rhs) const {
// cast rhs to base and delegate to operator in base
return base_type::operator==(static_cast<const base_type&>(rhs));
}
};
int main() {
MyVariant<std::string, char> v;
v = 1;
std::cout << v.type_size() << " " << sizeof(char) << std::endl;
v = std::string("foo");
std::cout << v.type_size() << " " << sizeof(std::string) << std::endl;
// comparison operators need workaround shown above
MyVariant<std::string, char> a, b;
a = 1; b = 1;
assert(a == b);
}
I want an empty state
boost::variant<boost::blank, bool, long, std::string>
There. That was much easier. No need for messy inheritance.
I want to give enum types
enum Type
{
NONE,
BOOL,
LONG,
STRING
};
struct GetType : public boost::static_visitor<Type>
{
Type operator()(boost::blank) {return NONE;}
Type operator()(bool) {return BOOL;}
Type operator()(long) {return LONG;}
Type operator()(const std::string&) {return STRING;}
};
//Get the type
Type t = boost::apply_visitor(GetType(), theData);
That was easy too. Plus, if you add a new type to the variant, your code will break if you don't update GetType to match.
The other two criteria require you to use a class, but you don't need inheritance. You need containment.
typedef boost::variant<boost::blank, std::string, long> VarType;
class MyVariant
{
public:
//Default construction will initialize with boost::blank.
MyVariant(char c) : m_var(std::string(1,c)) {}
MyVariant(const char* s) : m_var(std::string(s)) {}
MyVariant(int v) : m_var(long(v)) {}
MyVariant(long v) : m_var(long(v)) {}
VarType &operator *() {return m_var;}
const VarType &operator *() const {return m_var;}
private:
VarType m_var;
};
...
Type t = boost::apply_visitor(GetType(), *theData);
Finally my implementation based on Nicol Bolas's answer:
Variant.h
class Variant
{
public:
Variant() : v_(boost::blank()) {}
Variant(bool v) : v_(v) {}
Variant(long v) : v_(v) {}
Variant(int v) : v_(long(v)) {}
Variant(double v) : v_(v) {}
Variant(const std::string& s) : v_(s) {}
Variant(const char* s) : v_(std::string(s)) {}
typedef boost::variant <boost::blank, bool,
long, double, std::string> bstvar;
enum Type {
NONE, BOOL, // above underlying types
LONG, DOUBLE, STRING // and enum must be consistent:
}; // (order must be same)
operator bstvar& () { return v_; }
operator const bstvar& () const { return v_; }
bstvar & operator*() { return v_; }
bstvar const& operator*() const { return v_; }
bool empty () const { return type() == NONE; }
bool toBool () const { return boost::get<bool > (v_); }
long toLong () const { return boost::get<long > (v_); }
double toDouble () const { return boost::get<double> (v_); }
std::string const& toStr () const { return boost::get<std::string> (v_); }
std::string & toStr () { return boost::get<std::string> (v_); }
inline Type type () const { return (Type) v_.which(); }
static Type type (const std::string&);
static std::string type (Type t);
private: bstvar v_; // Data
};
Variant.cpp
#include "Variant.h"
#include <sstream>
#include <algorithm> //std::transform
Variant::Type Variant::type (const std::string& str)
{
std::string lower = str;
std::transform (lower.begin(), lower.end(), lower.begin(), ::tolower);
if (lower == "bool") return BOOL;
if (lower == "long") return LONG;
if (lower == "double") return DOUBLE;
if (lower == "string") return STRING;
else return NONE;
}
std::string Variant::type (Type t)
{
switch (t)
{
case NONE: return "none";
case BOOL: return "bool";
case LONG: return "long";
case DOUBLE: return "double";
case STRING: return "string";
default:
;//see below
}
std::ostringstream oss;
oss <<"Unexpected type="<< t;
return oss.str();
}
I tried compiling the following code from this page:
http://www.pdc.kth.se/training/Talks/C++/boost/libs/variant/doc/sample.html
Under "A binary tree implementation" and I got a ton of errors that I'm having trouble with solving. I'm using gcc 3.4.5 with codeblocks.
#include <iostream>
#include "boost/variant.hpp"
#include "boost/incomplete.hpp"
using boost::variant;
using boost::incomplete;
using std::cout;
using std::endl;
struct non_leaf_node; // Forward declaration
// Define a variant with these two types:
// 1) int
// 2) The (incomplete) non_leaf_node struct
typedef variant<int, incomplete<non_leaf_node> > tree_node;
struct non_leaf_node
{
non_leaf_node(const tree_node& l, int num, const tree_node& r)
: left_(l), right_(r), num_(num) { }
non_leaf_node(const non_leaf_node& other)
: left_(other.left_), right_(other.right_), num_(other.num_) { }
int num_;
tree_node left_;
tree_node right_;
};
struct tree_printer : boost::static_visitor<void>
{
void operator()(int n) const
{
cout << n << ' ';
}
void operator()(const non_leaf_node& node) const
{
boost::apply_visitor(*this, node.left_);
cout << node.num_ << ' ';
boost::apply_visitor(*this, node.right_);
}
};
int main(int, char* [] )
{
//Build a binary search tree:
non_leaf_node a(3,4, 6);
non_leaf_node b(19, 20, 23);
non_leaf_node c(a,10, b);
tree_node root(c);
//Perform an in-order walk
boost::apply_visitor(tree_printer(), root);
return 0;
}
And the traceback during compilation:
> C:\boostvariantBtree\boostvariantBtree.cpp||In
> constructor
> `non_leaf_node::non_leaf_node(const
> tree_node&, int, const tree_node&)':|
> C:\boostvariantBtree\boostvariantBtree.cpp|24|warning:
> `non_leaf_node::right_' will be
> initialized after|
> C:\boostvariantBtree\boostvariantBtree.cpp|22|warning:
> `int non_leaf_node::num_'|
> C:\boostvariantBtree\boostvariantBtree.cpp|19|warning:
> when initialized here|
> C:\boostvariantBtree\boostvariantBtree.cpp|24|warning:
> `non_leaf_node::right_' will be
> initialized after|
> C:\boostvariantBtree\boostvariantBtree.cpp|22|warning:
> `int non_leaf_node::num_'|
> C:\boostvariantBtree\boostvariantBtree.cpp|20|warning:
> when initialized here| C:\Program
> Files\CodeBlocks\MinGW\bin\..\lib\gcc\mingw32\3.4.5\..\..\..\..\include\boost\variant\variant.hpp||In
> member function `typename
> Visitor::result_type
> boost::detail::variant::invoke_visitor<Visitor>::internal_visit(T&,
> int) [with T = const
> boost::incomplete<non_leaf_node>,
> Visitor = const tree_printer]':|
> C:\Program
> Files\CodeBlocks\MinGW\bin\..\lib\gcc\mingw32\3.4.5\..\..\..\..\include\boost\variant\detail\visitation_impl.hpp|128|instantiated
> from `typename Visitor::result_type
> boost::detail::variant::visitation_impl_invoke_impl(int,
> Visitor&, VoidPtrCV, T*, mpl_::true_)
> [with Visitor =
> boost::detail::variant::invoke_visitor<const
> tree_printer>, VoidPtrCV = const
> void*, T =
> boost::incomplete<non_leaf_node>]'|
> C:\Program
> Files\CodeBlocks\MinGW\bin\..\lib\gcc\mingw32\3.4.5\..\..\..\..\include\boost\variant\detail\visitation_impl.hpp|170|instantiated
> from `typename Visitor::result_type
> boost::detail::variant::visitation_impl_invoke(int,
> Visitor&, VoidPtrCV, T*, NoBackupFlag,
> int) [with Visitor =
> boost::detail::variant::invoke_visitor<const
> tree_printer>, VoidPtrCV = const
> void*, T =
> boost::incomplete<non_leaf_node>,
> NoBackupFlag = boost::variant<int,
> boost::incomplete<non_leaf_node>,
> boost::detail::variant::void_,
> boost::detail::variant::void_,
> boost::detail::variant::void_,
> boost::detail::variant::void_,
> boost::detail::variant::void_, boo|
> C:\Program
> Files\CodeBlocks\MinGW\bin\..\lib\gcc\mingw32\3.4.5\..\..\..\..\include\boost\variant\detail\visitation_impl.hpp|256|instantiated
> from `typename Visitor::result_type
> boost::detail::variant::visitation_impl(int,
> int, Visitor&, VoidPtrCV,
> mpl_::false_, NoBackupFlag, Which*,
> step0*) [with Which = mpl_::int_<0>,
> step0 =
> boost::detail::variant::visitation_impl_step<boost::mpl::l_iter<boost::mpl::l_item<mpl_::long_<2l>,
> int,
> boost::mpl::l_item<mpl_::long_<1l>,
> boost::incomplete<non_leaf_node>,
> boost::mpl::l_end> > >,
> boost::mpl::l_iter<boost::mpl::l_end>
> >, Visitor = boost::detail::variant::invoke_visitor<const
> tree_printer>, | C:\Program
> Files\CodeBlocks\MinGW\bin\..\lib\gcc\mingw32\3.4.5\..\..\..\..\include\boost\variant\variant.hpp|1771|instantiated
> from `static typename
> Visitor::result_type
> boost::variant<T0, T1, T2, T3, T4, T5,
> T6, T7, T8, T9, T10, T11, T12, T13,
> T14, T15, T16, T17, T18,
> T19>::internal_apply_visitor_impl(int,
> int, Visitor&, VoidPtrCV) [with
> Visitor =
> boost::detail::variant::invoke_visitor<const
> tree_printer>, VoidPtrCV = const
> void*, T0_ = int, T1 =
> boost::incomplete<non_leaf_node>, T2 =
> boost::detail::variant::void_, T3 =
> boost::detail::variant::void_, T4 =
> boost::detail::variant::void_, T5 =
> boost::detail::variant::vo| C:\Program
> Files\CodeBlocks\MinGW\bin\..\lib\gcc\mingw32\3.4.5\..\..\..\..\include\boost\variant\variant.hpp|1796|instantiated
> from `typename Visitor::result_type
> boost::variant<T0, T1, T2, T3, T4, T5,
> T6, T7, T8, T9, T10, T11, T12, T13,
> T14, T15, T16, T17, T18,
> T19>::internal_apply_visitor(Visitor&)
> const [with Visitor =
> boost::detail::variant::invoke_visitor<const
> tree_printer>, T0_ = int, T1 =
> boost::incomplete<non_leaf_node>, T2 =
> boost::detail::variant::void_, T3 =
> boost::detail::variant::void_, T4 =
> boost::detail::variant::void_, T5 =
> boost::detail::variant::void_, T6 =
> boost::detail::variant::void_, T7 =
> boost:| C:\Program
> Files\CodeBlocks\MinGW\bin\..\lib\gcc\mingw32\3.4.5\..\..\..\..\include\boost\variant\variant.hpp|1820|instantiated
> from `typename Visitor::result_type
> boost::variant<T0, T1, T2, T3, T4, T5,
> T6, T7, T8, T9, T10, T11, T12, T13,
> T14, T15, T16, T17, T18,
> T19>::apply_visitor(Visitor&) const
> [with Visitor = const tree_printer,
> T0_ = int, T1 =
> boost::incomplete<non_leaf_node>, T2 =
> boost::detail::variant::void_, T3 =
> boost::detail::variant::void_, T4 =
> boost::detail::variant::void_, T5 =
> boost::detail::variant::void_, T6 =
> boost::detail::variant::void_, T7 =
> boost::detail::variant::void_, T8 =
> boost::detail::vari| C:\Program
> Files\CodeBlocks\MinGW\bin\..\lib\gcc\mingw32\3.4.5\..\..\..\..\include\boost\variant\detail\apply_visitor_unary.hpp|76|instantiated
> from `typename Visitor::result_type
> boost::apply_visitor(const Visitor&,
> Visitable&) [with Visitor =
> tree_printer, Visitable = const
> tree_node]'|
> C:\boostvariantBtree\boostvariantBtree.cpp|34|instantiated
> from here| C:\Program
> Files\CodeBlocks\MinGW\bin\..\lib\gcc\mingw32\3.4.5\..\..\..\..\include\boost\variant\variant.hpp|832|error:
> no match for call to `(const
> tree_printer) (const
> boost::incomplete<non_leaf_node>&)'|
> C:\boostvariantBtree\boostvariantBtree.cpp|29|note:
> candidates are: void
> tree_printer::operator()(int) const|
> C:\boostvariantBtree\boostvariantBtree.cpp|33|note:
> void tree_printer::operator()(const
> non_leaf_node&) const| C:\Program
> Files\CodeBlocks\MinGW\bin\..\lib\gcc\mingw32\3.4.5\..\..\..\..\include\boost\variant\variant.hpp|832|error:
> return-statement with a value, in
> function returning 'void'| C:\Program
> Files\CodeBlocks\MinGW\bin\..\lib\gcc\mingw32\3.4.5\..\..\..\..\include\boost\variant\variant.hpp||In
> member function `typename
> Visitor::result_type
> boost::detail::variant::invoke_visitor<Visitor>::internal_visit(T&,
> int) [with T =
> boost::incomplete<non_leaf_node>,
> Visitor = const tree_printer]':|
> C:\Program
> Files\CodeBlocks\MinGW\bin\..\lib\gcc\mingw32\3.4.5\..\..\..\..\include\boost\variant\detail\visitation_impl.hpp|128|instantiated
> from `typename Visitor::result_type
> boost::detail::variant::visitation_impl_invoke_impl(int,
> Visitor&, VoidPtrCV, T*, mpl_::true_)
> [with Visitor =
> boost::detail::variant::invoke_visitor<const
> tree_printer>, VoidPtrCV = void*, T =
> boost::incomplete<non_leaf_node>]'|
> C:\Program
> Files\CodeBlocks\MinGW\bin\..\lib\gcc\mingw32\3.4.5\..\..\..\..\include\boost\variant\detail\visitation_impl.hpp|170|instantiated
> from `typename Visitor::result_type
> boost::detail::variant::visitation_impl_invoke(int,
> Visitor&, VoidPtrCV, T*, NoBackupFlag,
> int) [with Visitor =
> boost::detail::variant::invoke_visitor<const
> tree_printer>, VoidPtrCV = void*, T =
> boost::incomplete<non_leaf_node>,
> NoBackupFlag = boost::variant<int,
> boost::incomplete<non_leaf_node>,
> boost::detail::variant::void_,
> boost::detail::variant::void_,
> boost::detail::variant::void_,
> boost::detail::variant::void_,
> boost::detail::variant::void_,
> boost::de| C:\Program
> Files\CodeBlocks\MinGW\bin\..\lib\gcc\mingw32\3.4.5\..\..\..\..\include\boost\variant\detail\visitation_impl.hpp|256|instantiated
> from `typename Visitor::result_type
> boost::detail::variant::visitation_impl(int,
> int, Visitor&, VoidPtrCV,
> mpl_::false_, NoBackupFlag, Which*,
> step0*) [with Which = mpl_::int_<0>,
> step0 =
> boost::detail::variant::visitation_impl_step<boost::mpl::l_iter<boost::mpl::l_item<mpl_::long_<2l>,
> int,
> boost::mpl::l_item<mpl_::long_<1l>,
> boost::incomplete<non_leaf_node>,
> boost::mpl::l_end> > >,
> boost::mpl::l_iter<boost::mpl::l_end>
> >, Visitor = boost::detail::variant::invoke_visitor<const
> tree_printer>, | C:\Program
> Files\CodeBlocks\MinGW\bin\..\lib\gcc\mingw32\3.4.5\..\..\..\..\include\boost\variant\variant.hpp|1771|instantiated
> from `static typename
> Visitor::result_type
> boost::variant<T0, T1, T2, T3, T4, T5,
> T6, T7, T8, T9, T10, T11, T12, T13,
> T14, T15, T16, T17, T18,
> T19>::internal_apply_visitor_impl(int,
> int, Visitor&, VoidPtrCV) [with
> Visitor =
> boost::detail::variant::invoke_visitor<const
> tree_printer>, VoidPtrCV = void*, T0_
> = int, T1 = boost::incomplete<non_leaf_node>, T2 =
> boost::detail::variant::void_, T3 =
> boost::detail::variant::void_, T4 =
> boost::detail::variant::void_, T5 =
> boost::detail::variant::void_, T|
> C:\Program
> Files\CodeBlocks\MinGW\bin\..\lib\gcc\mingw32\3.4.5\..\..\..\..\include\boost\variant\variant.hpp|1785|instantiated
> from `typename Visitor::result_type
> boost::variant<T0, T1, T2, T3, T4, T5,
> T6, T7, T8, T9, T10, T11, T12, T13,
> T14, T15, T16, T17, T18,
> T19>::internal_apply_visitor(Visitor&)
> [with Visitor =
> boost::detail::variant::invoke_visitor<const
> tree_printer>, T0_ = int, T1 =
> boost::incomplete<non_leaf_node>, T2 =
> boost::detail::variant::void_, T3 =
> boost::detail::variant::void_, T4 =
> boost::detail::variant::void_, T5 =
> boost::detail::variant::void_, T6 =
> boost::detail::variant::void_, T7 =
> boost::detai| C:\Program
> Files\CodeBlocks\MinGW\bin\..\lib\gcc\mingw32\3.4.5\..\..\..\..\include\boost\variant\variant.hpp|1810|instantiated
> from `typename Visitor::result_type
> boost::variant<T0, T1, T2, T3, T4, T5,
> T6, T7, T8, T9, T10, T11, T12, T13,
> T14, T15, T16, T17, T18,
> T19>::apply_visitor(Visitor&) [with
> Visitor = const tree_printer, T0_ =
> int, T1 =
> boost::incomplete<non_leaf_node>, T2 =
> boost::detail::variant::void_, T3 =
> boost::detail::variant::void_, T4 =
> boost::detail::variant::void_, T5 =
> boost::detail::variant::void_, T6 =
> boost::detail::variant::void_, T7 =
> boost::detail::variant::void_, T8 =
> boost::detail::variant::v| C:\Program
> Files\CodeBlocks\MinGW\bin\..\lib\gcc\mingw32\3.4.5\..\..\..\..\include\boost\variant\detail\apply_visitor_unary.hpp|76|instantiated
> from `typename Visitor::result_type
> boost::apply_visitor(const Visitor&,
> Visitable&) [with Visitor =
> tree_printer, Visitable = tree_node]'|
> C:\boostvariantBtree\boostvariantBtree.cpp|49|instantiated
> from here| C:\Program
> Files\CodeBlocks\MinGW\bin\..\lib\gcc\mingw32\3.4.5\..\..\..\..\include\boost\variant\variant.hpp|832|error:
> no match for call to `(const
> tree_printer)
> (boost::incomplete<non_leaf_node>&)'|
> C:\boostvariantBtree\boostvariantBtree.cpp|29|note:
> candidates are: void
> tree_printer::operator()(int) const|
> C:\boostvariantBtree\boostvariantBtree.cpp|33|note:
> void tree_printer::operator()(const
> non_leaf_node&) const| C:\Program
> Files\CodeBlocks\MinGW\bin\..\lib\gcc\mingw32\3.4.5\..\..\..\..\include\boost\variant\variant.hpp|832|error:
> return-statement with a value, in
> function returning 'void'| ||=== Build
> finished: 4 errors, 6 warnings ===|
As far as I see, current boost seems not to have incomplete.hpp.
If your boost is recent one,
by removing the line
#include "boost/incomplete.hpp" and using boost::incomplete;,
and replacing the line
typedef variant<int, incomplete<non_leaf_node> > tree_node;
with
typedef variant<int, boost::recursive_wrapper<non_leaf_node> > tree_node;
probably the code will be compiled.
Here is a test on ideone.
If you need a recursive type,
this document
Recursive variant types
might help.