错误适应与BOOST_FUSION_ADAPT_ADT类时 [英] Error when adapting a class with BOOST_FUSION_ADAPT_ADT
问题描述
我有以下类:
的#ifndef WFRACTAL_FRACTAL_METADATA_H_
#定义WFRACTAL_FRACTAL_METADATA_H_#包括LT&;串GT;命名空间WFractal {
命名空间的分形{类的元数据{上市: 无效setAuthorName(常量标准::字符串&安培;名);
无效setAuthorEMail(常量标准::字符串&安培;电子邮件);
无效setBriefDescription(常量标准::字符串&安培;简介);
无效setCompleteDescription(常量标准::字符串&安培;说明);
标准::字符串getAuthorName()const的;
标准::字符串getAuthorEMail()const的;
标准::字符串getBriefDescription()const的;
标准::字符串getCompleteDescription()const的;上市: 布尔运算符==(const的元数据和安培;其他);私人的: 标准::字符串m_name;
标准::字符串m_email;
标准::字符串m_brief;
标准::字符串m_description;
};} //命名空间中的分形
} //命名空间WFractal#ENDIF //!WFRACTAL_FRACTAL_METADATA_H_
我想用解析它的boost ::精神
从下列文件内容:
{元
笔者=我;
电子邮件=myemail;
简短=简要说明;
说明=完整说明;
}
我从的我可以使用 BOOST_FUSION_ADAPT_STRUCT
为了解析这个页面。这是我的语法模板:
的#ifndef WFRACTAL_FRACTAL_PARSER_METADATAGRAMMAR_H_
#定义WFRACTAL_FRACTAL_PARSER_METADATAGRAMMAR_H_#包括LT&;升压/融合/调整/ ADT / adapt_adt.hpp>
#包括LT&;升压/融合/有/ adapt_adt.hpp>
#包括LT&;升压/精神/有/ qi_no_case.hpp>
#包括LT&;串GT;
#包括分形/ Metadata.hBOOST_FUSION_ADAPT_ADT(
WFractal ::分形::元数据,
(obj.getAuthorName(),obj.setAuthorName(VAL))
(obj.getAuthorEMail(),obj.setBriefDescription(VAL))
(obj.getBriefDescription(),obj.setCompleteDescription(VAL))
(obj.getCompleteDescription(),obj.setAuthorEMail(VAL))
)命名空间WFractal {
命名空间的分形{
命名空间解析器{模板< typename的迭代器>
结构MetadataParser:提振精神:: ::气::语法<迭代器,元数据()的boost ::精神:: ASCII ::空间类型> {
MetadataParser():MetadataParser :: base_type(开始){
使用boost ::精神::补气:: int_;
使用boost ::精神::补气::点燃;
使用boost ::精神::补气:: double_;
使用boost ::精神::补气::词位;
使用boost ::精神:: ASCII :: char_;
使用boost ::精神:: ASCII :: NO_CASE; quoted_string%=语义[''>> +(char_ - ')GT;> '']; 启动(%)=
NO_CASE [亮起(元数据)
>> {
>> NO_CASE [亮起(作家)]>> '='>> quoted_string>> ';'
>> NO_CASE [亮(电子邮件)>> '='>> quoted_string>> ';'
>> NO_CASE [亮起(简报)>> '='>> quoted_string>> ';'
>> NO_CASE [点亮(说明)]≥> '='>> quoted_string>> ';'
>> }
;
} 提振精神:: ::气::规则<迭代器,标准::字符串(),升压::精神:: ASCII ::空间类型> quoted_string;
提振精神:: ::气::规则<迭代器,元数据()的boost ::精神:: ASCII ::空间类型>开始;
};} //命名空间分析器
} //命名空间中的分形
} //命名空间WFractal#ENDIF //!WFRACTAL_FRACTAL_PARSER_METADATAGRAMMAR_H_
当我创建这个语法的一个实例(总是沿着页面的例子),我得到编译器错误:
的typedef字符串::为const_iterator StringIterator;
typedef的解析器:: MetadataParser< StringIterator> MetadataParser;
MetadataParser分析器;
我得到了很多错误(典型的提振...)和我注意到在他们里面这个错误的许多副本:
的src /分形/ FileFactory.cpp:27:17:从这里需要
/usr/include/boost/spirit/home/qi/detail/assign_to.hpp:152:18:错误:调用'的boost ::融合::扩展:: adt_attribute_proxy&LT没有匹配功能; WFractal ::分形::元,0,假> :: adt_attribute_proxy(常量的std :: __ cxx11 :: basic_string的<焦炭>&安培;)
ATTR =的static_cast<属性与GT;(VAL);
我在做什么错?我怎样才能解决这个问题?
修改
正如所建议的M.S.我已经添加了的#include<升压/精神/有/ support_adapt_adt_attributes.hpp方式>
头,但是这是行不通的。
的#ifndef WFRACTAL_FRACTAL_PARSER_METADATAPARSER_H_
#定义WFRACTAL_FRACTAL_PARSER_METADATAPARSER_H_#包括LT&;升压/配置/ warning_disable.hpp>
#包括LT&;升压/精神/有/ qi.hpp>
#包括LT&;升压/精神/有/ phoenix_core.hpp>
#包括LT&;升压/精神/有/ phoenix_operator.hpp>
#包括LT&;升压/精神/有/ phoenix_object.hpp>
#包括LT&;升压/融合/有/ io.hpp>
#包括LT&;升压/融合/调整/ ADT / adapt_adt.hpp>
#包括LT&;升压/融合/有/ adapt_adt.hpp>
#包括LT&;升压/精神/有/ support_adapt_adt_attributes.hpp>
#包括LT&;串GT;
#包括分形/ Metadata.hBOOST_FUSION_ADAPT_ADT(
WFractal ::分形::元数据,
(obj.getAuthorName(),obj.setAuthorName(VAL))
(obj.getAuthorEMail(),obj.setAuthorEMail(VAL))
(obj.getBriefDescription(),obj.setBriefDescription(VAL))
(obj.getCompleteDescription(),obj.setCompleteDescription(VAL))
)命名空间WFractal {
命名空间的分形{
命名空间解析器{模板< typename的迭代器>
结构MetadataParser:提振精神:: ::气::语法<迭代器,元数据()的boost ::精神:: ASCII ::空间类型> {
MetadataParser():MetadataParser :: base_type(开始){
使用boost ::精神::补气::点燃;
使用boost ::精神::补气::词位;
使用boost ::精神:: ASCII :: char_;
使用boost ::精神:: ASCII :: NO_CASE; quoted_string%=语义[''>> +(char_ - ')GT;> '']; 启动(%)=
NO_CASE [亮起(元数据)
>> {
>> ((NO_CASE [亮起(作家)]>>'='>> quoted_string>>';')
^(NO_CASE [亮(电子邮件)>>'='>> quoted_string>>';')
^(NO_CASE [亮起(简报)>>'='>> quoted_string>>';')
^(NO_CASE [点亮(说明)]≥>'='>> quoted_string>>';'))
>> }
;
} 提振精神:: ::气::规则<迭代器,标准::字符串(),升压::精神:: ASCII ::空间类型> quoted_string;
提振精神:: ::气::规则<迭代器,元数据()的boost ::精神:: ASCII ::空间类型>开始;
};} //命名空间分析器
} //命名空间中的分形
} //命名空间WFractal#ENDIF //!WFRACTAL_FRACTAL_PARSER_METADATAPARSER_H_
嗯。
与模块化升压和Git很长时间的斗争后...我发现这是一个倒退。
回归了这个pull请求得到部分修正:
不幸的是,它仍然打破了置换分析器的presence。我和 BOOST_FUSION_ADAPT_STRUCT
测试,以验证它是不以其他方式打破。
我会减少样品添加到PR征求意见。同时,这里是做整装重现:
<大骨节病> 住在Coliru 骨节病>
的#include&LT;升压/精神/有/ qi.hpp&GT;
#包括LT&;升压/融合/ adapted.hpp&GT;
#包括LT&;&iostream的GT;类Foo {
上市:
字符常量和放大器;木屐()const的{返回; }
字符常量和放大器; getB()const的{回复B; } 无效SETA(char值){a =值; }
无效组B(char值){B =价值; }
私人的:
烧焦A,B;
};BOOST_FUSION_ADAPT_ADT(
美孚,
(字符常量和放大器;,字符常量和放大器;,obj.getA(),obj.setA(VAL))
(字符常量和放大器;,字符常量和放大器;,obj.getB(),obj.setB(VAL))
)
诠释主(){
命名空间补气=的boost ::精神::补气; 提振精神:: :: istream_iterator F(的std :: CIN),L; //输入例如A = A; B =;
富富; BOOL R =气::解析(F,L,
#如果0 //编译失败
(A =&GT;&GT;气虚:: char_&GT;&GT;';')
^(B =&GT;&GT;气虚:: char_&GT;&GT;';')
#else伪//使用FIX汇集了来自PR#153
(A =&GT;&GT;气虚:: char_&GT;&GT;';')
&GT;&GT; (B =&GT;&GT;气虚:: char_&GT;&GT;';')
#万一
,富); 如果(r)的
性病::法院LT&;&LT; 经分析:&LT;&LT;提高::融合:: as_vector(富)&LT;&LT; \\ n;
其他
的std :: CERR&LT;&LT; 解析失败\\ n;
}
如果你,但是,更改#如果1
到 0#如果
,你得到的输出:
解析的:(A B)
注意当然,这是假设你使用具有PR 153的应用。一个分支
块引用>I've the following class:
#ifndef WFRACTAL_FRACTAL_METADATA_H_ #define WFRACTAL_FRACTAL_METADATA_H_ #include <string> namespace WFractal { namespace Fractal { class Metadata { public: void setAuthorName(const std::string &name); void setAuthorEMail(const std::string &email); void setBriefDescription(const std::string &brief); void setCompleteDescription(const std::string &description); std::string getAuthorName() const; std::string getAuthorEMail() const; std::string getBriefDescription() const; std::string getCompleteDescription() const; public: bool operator==(const Metadata &other); private: std::string m_name; std::string m_email; std::string m_brief; std::string m_description; }; } // namespace Fractal } // namespace WFractal #endif // !WFRACTAL_FRACTAL_METADATA_H_
I want to parse it using
boost::spirit
from following file content:metadata { author = "Me"; email = "myemail"; brief = "brief description"; description = "complete description"; }
I've read from this page that I can use
BOOST_FUSION_ADAPT_STRUCT
in order to parse it. This is my grammar template:#ifndef WFRACTAL_FRACTAL_PARSER_METADATAGRAMMAR_H_ #define WFRACTAL_FRACTAL_PARSER_METADATAGRAMMAR_H_ #include <boost/fusion/adapted/adt/adapt_adt.hpp> #include <boost/fusion/include/adapt_adt.hpp> #include <boost/spirit/include/qi_no_case.hpp> #include <string> #include "Fractal/Metadata.h" BOOST_FUSION_ADAPT_ADT( WFractal::Fractal::Metadata, (obj.getAuthorName(), obj.setAuthorName(val)) (obj.getAuthorEMail(), obj.setBriefDescription(val)) (obj.getBriefDescription(), obj.setCompleteDescription(val)) (obj.getCompleteDescription(), obj.setAuthorEMail(val)) ) namespace WFractal { namespace Fractal { namespace Parser { template <typename Iterator> struct MetadataParser : boost::spirit::qi::grammar<Iterator, Metadata(), boost::spirit::ascii::space_type> { MetadataParser() : MetadataParser::base_type(start) { using boost::spirit::qi::int_; using boost::spirit::qi::lit; using boost::spirit::qi::double_; using boost::spirit::qi::lexeme; using boost::spirit::ascii::char_; using boost::spirit::ascii::no_case; quoted_string %= lexeme['"' >> +(char_ - '"') >> '"']; start %= no_case[lit("metadata")] >> '{' >> no_case[lit("author")] >> '=' >> quoted_string >> ';' >> no_case[lit("email")] >> '=' >> quoted_string >> ';' >> no_case[lit("brief")] >> '=' >> quoted_string >> ';' >> no_case[lit("description")] >> '=' >> quoted_string >> ';' >> '}' ; } boost::spirit::qi::rule<Iterator, std::string(), boost::spirit::ascii::space_type> quoted_string; boost::spirit::qi::rule<Iterator, Metadata(), boost::spirit::ascii::space_type> start; }; } // namespace Parser } // namespace Fractal } // namespace WFractal #endif // !WFRACTAL_FRACTAL_PARSER_METADATAGRAMMAR_H_
When I create an instance of this grammar (always following the page example), I obtain compiler error:
typedef string::const_iterator StringIterator; typedef Parser::MetadataParser<StringIterator> MetadataParser; MetadataParser parser;
I obtain a lot of errors (typical of boost...) and I've noticed inside them many copy of this error:
src/Fractal/FileFactory.cpp:27:17: required from here /usr/include/boost/spirit/home/qi/detail/assign_to.hpp:152:18: error: no matching function for call to ‘boost::fusion::extension::adt_attribute_proxy<WFractal::Fractal::Metadata, 0, false>::adt_attribute_proxy(const std::__cxx11::basic_string<char>&)’ attr = static_cast<Attribute>(val);
What I'm doing wrong? How can I fix it?
EDIT
As suggested by m.s. I've added the
#include <boost/spirit/include/support_adapt_adt_attributes.hpp>
header but this is not working.#ifndef WFRACTAL_FRACTAL_PARSER_METADATAPARSER_H_ #define WFRACTAL_FRACTAL_PARSER_METADATAPARSER_H_ #include <boost/config/warning_disable.hpp> #include <boost/spirit/include/qi.hpp> #include <boost/spirit/include/phoenix_core.hpp> #include <boost/spirit/include/phoenix_operator.hpp> #include <boost/spirit/include/phoenix_object.hpp> #include <boost/fusion/include/io.hpp> #include <boost/fusion/adapted/adt/adapt_adt.hpp> #include <boost/fusion/include/adapt_adt.hpp> #include <boost/spirit/include/support_adapt_adt_attributes.hpp> #include <string> #include "Fractal/Metadata.h" BOOST_FUSION_ADAPT_ADT( WFractal::Fractal::Metadata, (obj.getAuthorName(), obj.setAuthorName(val)) (obj.getAuthorEMail(), obj.setAuthorEMail(val)) (obj.getBriefDescription(), obj.setBriefDescription(val)) (obj.getCompleteDescription(), obj.setCompleteDescription(val)) ) namespace WFractal { namespace Fractal { namespace Parser { template <typename Iterator> struct MetadataParser : boost::spirit::qi::grammar<Iterator, Metadata(), boost::spirit::ascii::space_type> { MetadataParser() : MetadataParser::base_type(start) { using boost::spirit::qi::lit; using boost::spirit::qi::lexeme; using boost::spirit::ascii::char_; using boost::spirit::ascii::no_case; quoted_string %= lexeme['"' >> +(char_ - '"') >> '"']; start %= no_case[lit("metadata")] >> '{' >> ((no_case[lit("author")] >> '=' >> quoted_string >> ';') ^ (no_case[lit("email")] >> '=' >> quoted_string >> ';') ^ (no_case[lit("brief")] >> '=' >> quoted_string >> ';') ^ (no_case[lit("description")] >> '=' >> quoted_string >> ';')) >> '}' ; } boost::spirit::qi::rule<Iterator, std::string(), boost::spirit::ascii::space_type> quoted_string; boost::spirit::qi::rule<Iterator, Metadata(), boost::spirit::ascii::space_type> start; }; } // namespace Parser } // namespace Fractal } // namespace WFractal #endif // !WFRACTAL_FRACTAL_PARSER_METADATAPARSER_H_
解决方案Hmm.
After very long struggle with Modular Boost and git... I've found that this is a regression.
The regression has been partially fixed by this pull request:
Sadly, it's still broken in the presence of the permutation parser. I've tested with
BOOST_FUSION_ADAPT_STRUCT
to verify that it is not broken in some other way.I'll add the reduced sample to the PR for comments. Meanwhile, here's the reproducer made selfcontained:
#include <boost/spirit/include/qi.hpp> #include <boost/fusion/adapted.hpp> #include <iostream> class Foo { public: char const& getA() const { return a; } char const& getB() const { return b; } void setA(char value) { a = value; } void setB(char value) { b = value; } private: char a, b; }; BOOST_FUSION_ADAPT_ADT( Foo, (char const&, char const&, obj.getA(), obj.setA(val)) (char const&, char const&, obj.getB(), obj.setB(val)) ) int main() { namespace qi = boost::spirit::qi; boost::spirit::istream_iterator f(std::cin), l; // input e.g. "a=a;b=b;" Foo foo; bool r = qi::parse(f, l, #if 0 // FAILS TO COMPILE ("a=" >> qi::char_ >> ';') ^ ("b=" >> qi::char_ >> ';') #else // COMPILES WITH FIX FROM PR #153 ("a=" >> qi::char_ >> ';') >> ("b=" >> qi::char_ >> ';') #endif , foo); if (r) std::cout << "Parsed: " << boost::fusion::as_vector(foo) << "\n"; else std::cerr << "Parse failed\n"; }
If you, however, change the
#if 1
to#if 0
, you get the output:Parsed: (a b)
Note of course that's assuming you use a branch that has the PR 153 applied.
这篇关于错误适应与BOOST_FUSION_ADAPT_ADT类时的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!