2016-05-18 17 views
1

私はboost :: variantについて学び、apply_visitorを使ってメンバーにアクセスしています。だから、私は次の例を書いた。 クラスメンバーとしてテンプレートオブジェクトへのポインタを持っています。 apply_visitorを使用してそれらにアクセスしたいと思います。boost :: 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; 
} 

私は上記のコンパイルから取得するエラーは、私はブーストからC < 1> *を削除する場合には、コンパイルし、正常に動作します

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); 

です::バリアント宣言。

任意の提案を高く評価されるだろう。

答えて

1

すべての訪問者関数は、基本クラス:boost::static_visitor<C<dim> *>で定義されているスキームに従う必要があります。

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>をひそかすることはできませんので:参照 - operator()の戻り値は常にC<dim> *ないC<t>*なければならないことを意味

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; 
    } 
+0

が、私はブースト::バリアントを使用してテンプレートオブジェクトの異質マップを作成しようとしています:以下のように - あなたはこれを解決するために行う可能性がありますどのような

は、基本クラスを導入することです。 static_visitorを使ってオブジェクトへのポインタを取得する方法を理解したかったので、コンストラクタ内で使用しました。両方とも、tとdimはまだsize_tオブジェクトなので、違うはずはありませんか?ただし、同じエラーが発生します。具体的には、次のエラーが私に混乱しています。 21:22:エラー: 'A :: C <1ul> *'を 'A :: C <2ul> *'に変換できません。 メンバ関数 'A :: C * A :: C :: operator()(A :: C *)const [長い符号なしint t = 1ul; long unsigned int dim = 2ul] ': – ZincFur

+1

コメントを見る私は 'return s;'の右に置く。これを 'return nullptr; 'に変更すると、エラーは発生しません。しかし、私はこれがあなたが望むものではないと確信しています... 'C <1>'と 'C <2>'は決して関連する型ではないことを覚えておいてください。両方が同じクラステンプレートのインスタンスであるという事実は、 ... – PiotrNycz

+0

しかし、CBaseのような基本クラスを導入することで、 'C <1>'と 'C <2>'を関連付けることができ、演算子の戻り値と 'boost :: static_visitor'へのパラメータとして' CBase * – PiotrNycz

関連する問題