2016-07-04 47 views
1

,同時學習如何使用升壓精神,鳳凰和融合庫,我來翻過不上MSVC(2015年版14)編譯和促進這個小例子1.61.0鑄造屬性的boost ::變種

#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: '的boost ::詳細::變種:: make_initializer_node ::申請:: initializer_node ::初始化': 沒有5個重載的可能轉換所有參數類型

類似的問題已被報道here雖然我無法理解答案是如何解決問題的,以及這是否真的是同樣的問題,因爲看起來所有類型都正確提供(不需要類型轉換)。

回答

1

問題似乎在於Spirit不會選擇自定義transform_attribute自定義點。它使用默認的,並且試圖從const U(!!)構建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專業化改變

噶總是與常量值的內部工作原理。

全樣本(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'here'。 – llonesmiz