2016-07-04 7 views
1

はブーストスピリット、鳳凰と融合ライブラリを使用する方法を学ぶ一方で、私はMSVC(2015、バージョン14)でコンパイルし、後押ししません。この最小限の例accrossに来た1.61.0鋳造属性::バリアント

#include <boost/spirit/include/karma.hpp> 
#include <boost/variant/variant.hpp> 

namespace ka = boost::spirit::karma; 

struct U /* a kind of union (legacy code)*/ 
    { 
     bool kind; 
     double foo; /* if kind = true */ 
     size_t bar; /* if kind = false */ 
    }; 

typedef boost::variant<double, size_t> UVariant; 

namespace boost { namespace spirit { namespace traits { 
    template<> 
    struct transform_attribute<U,UVariant,ka::domain> 
    { 
     typedef UVariant type; 
     static type pre(U & u) { 
      switch (u.kind) 
      { 
      case true: 
       return type(u.foo); 
      case false: 
       return type(u.bar); 
      } 
     } 
    }; 
}}} 

typedef std::back_insert_iterator<std::string> iterator; 

class grm: public ka::grammar<iterator, U()> 
{ 
public: 
    grm():grm::base_type(start) 
    { 
     start = ka::attr_cast<U,UVariant >(foo | bar); 
     foo = ka::double_; 
     bar = ka::uint_; 
     */ 
    } 
private: 
    ka::rule<iterator,U()> start; 
    ka::rule<iterator,double()> foo; 
    ka::rule<iterator,size_t()> bar; 
}; 

int main(int argc, char * argv[]) 
{ 
    grm g; 
    U u; 
    u.kind = true; 
    u.foo = 1.0; 

    std::string generated; 
    std::back_insert_iterator<std::string> sink(generated); 
    ka::generate(sink,g,u); 


    return 0; 
} 

エラーC2665: 'ブースト::詳細::バリアント:: make_initializer_node ::適用:: initializer_node ::初期化':

は、それから私は、次のエラーメッセージを取得5つのオーバーロードの どれも可能性すべての引数型を変換する

回答がどのように問題に対処しているのか、これが実際にすべてのタイプが正しく提供されているように(タイプ変換の必要なし)同じ問題かどうかはわかりませんでしたが、同様の問題が報告されていますhere

答えて

1

スピリットがあなたのカスタムカスタマイズポイントを選んでいないという問題があるようです。これはデフォルトのものを使用しており、(!!)からboost::variant<double,size_t>を作成しようとしますが、これは明らかに失敗します。

namespace boost { namespace spirit { namespace traits { 
    template<> 
    struct transform_attribute<const U,UVariant,ka::domain> 
           ^^^^^^^ 
    { 
     typedef UVariant type; 
     static type pre(const U & u) { 
         ^^^^^^^ 
      //same as before 
     } 
    }; 
}}} 

し、それはカルマによってピックアップされ、すべてが動作します:あなたがtransform_attributeのあなたの専門分野を変更する必要があるので、

カルマは常に内部的にconstの値で動作します。

全サンプル(On rextester):

#include <boost/spirit/include/karma.hpp> 
#include <boost/variant/variant.hpp> 

namespace ka = boost::spirit::karma; 

struct U /* a kind of union (legacy code)*/ 
    { 
     bool kind; 
     double foo; /* if kind = true */ 
     size_t bar; /* if kind = false */ 
    }; 

typedef boost::variant<double, size_t> UVariant; 

namespace boost { namespace spirit { namespace traits { 
    template<> 
    struct transform_attribute<const U,UVariant,ka::domain> 
    { 
     typedef UVariant type; 
     static type pre(const U & u) { 
      if(u.kind) 
      { 
       return type(u.foo); 
      } 
      else 
      { 
       return type(u.bar); 
      } 
     } 
    }; 
}}} 

typedef std::back_insert_iterator<std::string> iterator; 

class grm: public ka::grammar<iterator, U()> 
{ 
public: 
    grm():grm::base_type(start) 
    { 
     start = ka::attr_cast<UVariant>(foo | bar); 
     foo = ka::double_; 
     bar = ka::uint_; 
    } 
private: 
    ka::rule<iterator,U()> start; 
    ka::rule<iterator,double()> foo; 
    ka::rule<iterator,size_t()> bar; 
}; 

int main(int argc, char * argv[]) 
{ 
    grm g; 
    U u; 
    u.kind = false; 
    u.foo = 1.0; 
    u.bar = 34; 

    std::string generated; 
    std::back_insert_iterator<std::string> sink(generated); 
    ka::generate(sink,g,u); 

    std::cout << generated << std::endl; 


    return 0; 
} 
+0

それは仕事をして、ありがとうございました。あなたは、経験によって、またはコンパイラのx koエラーメッセージを精査して知っていましたか? – Heyji

+0

Clangのエラーメッセージはかなり明確で、それが私を助けました。正確なエラーには、 'boost :: spirit :: karma :: transform_attribute 、void> :: pre 'がここで要求されました。 – llonesmiz