2017-04-10 15 views
1

私は2つのクラスを持ち、keyの性質によって、boost::variantの構造体の値を取得したいと考えています。コードは以下の通りです。私は取得しています構造体オブジェクトでBoost Variantを使用する方法C++

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

using namespace std; 

class A { 
    public: 
    struct greeting { 
     string hello; 
}; 


class B { 
    public: 
    struct greeting { 
     string bye; 
    }; 
}; 

typedef boost::variant<A::greeting, B::greeting> greet; 

greet getG(string key) { 
    greet g; 
    if (key == "A") { 
     g.hello = "MY ENEMY"; // this line doesn't work 
    } 
    else { 
     g.bye = "MY FRIEND"; // nor this line 
    } 
    return g; 
}; 

int main() { 
    A a; 
    B b; 
    greet h = getG("A"); 
    A::greeting my = boost::get<A::greeting>(h); 
    cout << my.hello << endl; 
    return 0; 
} 

正確なエラーは次のとおりです。 error: no member named 'hello' in 'boost::variant<A::greeting, B::greeting, boost::detail::variant::void_, boost::detail::variant::void_, ...>' g.hello = "MY ENEMY";error: no member named 'bye' in 'boost::variant<A::greeting, B::greeting, .../>' g.bye = "MY FRIEND";

すべてのヘルプは高く評価されています。

+0

行番号が特定の行を見つけることが容易になりますが、私たちは、コードをコピーし、それを自分自身をしようとするために、それはまた、非常に難しいことになります。エラーがある行をマークするコメントで十分です。あなたの問題については –

+0

、特定の構造への参照を取得するには、[ '後押し:: GET'](http://www.boost.org/doc/libs/1_63_0/doc/html/boost/get_idp1003723808.html)を使用します。 –

答えて

2

バリアント型は.hello.byeメンバーを持っていません。 「訪問者」機能を介してアクセスできます。しかし、訪問者が適切なタイプに適用されていないときに、何をすべきかを決める必要があります。あなたはBoostを使用していないと思います.Variantは使用することを意図しています。 (例えば、条件文はうまく発色しません)。

http://www.boost.org/doc/libs/1_61_0/doc/html/variant/reference.html#variant.concepts.static-visitor

struct hello_visitor : boost::static_visitor<>{ 
    string const& msg; 
    hello_visitor(string const& msg) : msg(msg){} 
    void operator()(A::greeting& t) const{ 
     t.hello = msg; 
    } 
    void operator()(B::greeting& t) const{ 
     // throw? ignore? other? 
    } 
}; 

struct bye_visitor : boost::static_visitor<>{ 
    string const& msg; 
    bye_visitor(string const& msg) : msg(msg){} 
    void operator()(A::greeting& t) const{ 
     // throw? ignore? other? 
    } 
    void operator()(B::greeting& t) const{ 
     t.bye = msg; 
    } 
}; 


greet getG(string key) { 
    greet g; 
    if (key == "A") { // is "key" handling the type, if so you can delegate this to the library instead of doing this. 
     boost::apply_visitor(hello_visitor("MY ENEMY"), g); 
    } 
    else { 
     boost::apply_visitor(bye_visitor("MY FRIEND"), g); 
    } 
    return g; 
}; 
+0

(それを使用する方法については、たとえば[ブーストバリアントチュートリアル](http://www.boost.org/doc/libs/1_63_0/doc/html/variant/tutorial.html)を参照してください)私は、行を削除しました数字。コードをテストしたところ、「エラー:bye_visitorとhello_visitorを呼び出す関数がありません。私が迷っていることを私に指摘してもらえますか? – pseudo

+0

このコードは今動作します。あなたがしたいことは完全にはっきりしていません。実際のBoost.Variantといくつかのマニュアルバリアント(条件付き)を混在させているようです。 Boost.Variantのアイデアは、あなたが「実タイプ」の意思決定ツリーに対処する必要がないということです。 – alfC

+0

まさに私が必要としたもの。ありがとうございました。 – pseudo

関連する問題