我正在学习boost :: variant并使用apply_visitor访问其成员。所以,我写了下面的例子。 我有指向模板化对象的指针作为我的类成员。我想使用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;
}
我从编译上面得到的错误是
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);
如果我删除C&lt; 1&gt;它会编译并正常工作。 *来自boost :: variant声明。
任何建议都将受到高度赞赏。
答案 0 :(得分:1)
所有访问者函数必须遵循基类定义的方案:boost::static_visitor<C<dim> *>
。
这意味着operator()
的返回值必须始终为C<dim> *
而不是C<t>*
- 请参阅:
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
}
正如我在return s
右边的评论中所写 - 这不会编译 - 因为编译器无法将C<1>
转换为C<2>
。
你可能要做的就是引入基类 - 如下所示:
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;
}