2

boost-variant私はカスタムクラスを試していました。クラスのコンテンツにアクセスする安全な方法は を使用することだと理解しましたboost::static_visitor。以下のコードがコンパイルされない理由を知っていますか? boost::static_visitor使用するために署名/宣言に要件はありますか?

この質問を見つけましたなぜブースト::バリアントでこのカスタムタイプにアクセスできないのですか? しかし、私はそれを取得しませんでした。

よろしく

AFG

#include <iostream>
#include <algorithm>
#include <boost/variant.hpp>

struct CA{};

struct ca_visitor : public boost::static_visitor<CA>
{
    const CA& operator()(const CA& obj ) const { return obj;}
};

struct CB{};

struct cb_visitor : public boost::static_visitor<CB>
{
    const CB& operator()(const CB& obj) const { return obj;}
};

int main(){   
    typedef  boost::variant< 
        CA  
        ,CB >  v_type;

    v_type v;
    const CA& a = boost::apply_visitor( ca_visitor(), v );
}
4

1 に答える 1

5

まず、のテンプレート引数はboost::static_visitor<>、呼び出し演算子によって返される型を指定する必要があります。あなたの場合、ca_visitorの呼び出し演算子は、CA const&ではなく、を返しますCA

しかし、それは最大の問題ではありません。最大の問題は、どのように、そしてどのようvariant<>に機能static_visitor<>すべきかについて誤解しているように見えることです。

aの考え方は、テンプレート引数リストで指定した任意のタイプのboost::variant<>値を保持できるということです。そのタイプが何であるかわからないため、考えられる各ケースを処理するために、訪問者にいくつかのオーバーロードされた呼び出し演算子を提供します。

operator()したがって、訪問者を提供するときは、保持できるタイプを受け入れるために必要なすべてのオーバーロードがあることを確認する必要がありますvariant。そうしないと、Boost.Variantによってコンパイルエラーが生成されます(一部のケースを処理するのを忘れたため、これを実行します)。

これはあなたが直面している問題です:あなたの訪問者はタイプのオブジェクトを受け入れる呼び出し演算子を持っていませんCB

これは、との正しい使用例boost::variant<>ですstatic_visitor<>

#include <iostream>
#include <algorithm>
#include <boost/variant.hpp>

struct A{};
struct B{};

struct my_visitor : public boost::static_visitor<bool>
//                                               ^^^^
//                                               This must be the same as the
//                                               return type of your call 
//                                               operators
{
    bool operator() (const A& obj ) const { return true; }
    bool operator() (const B& obj) const { return false; }
};

int main()
{
    A a;
    B b;
    my_visitor mv;

    typedef boost::variant<A, B> v_type;

    v_type v = a;

    bool res = v.apply_visitor(mv);
    std::cout << res; // Should print 1

    v = b;

    res = v.apply_visitor(mv);
    std::cout << res; // Should print 0
}
于 2013-03-03T14:22:27.750 に答える