以下是boost spirit文档中的employee.cpp源文件。它是'struct employee'后跟一个宏,它告诉我们关于'struct employee'的融合,然后是员工解析器。
我正在尝试根据我的目的调整这个,但是我没有使用'struct employee',而是使用了许多类来代替'struct employee'。
我正在尝试为类替换'struct employee',但我没有看到宏在融合中做到这一点?我不想把它放在结构中的原因是因为我必须将它从struct复制到我的类,这似乎是不必要的,更不用说性能命中了。
在考虑了一点之后,我可能无法理解Fusion和元组的目的,因此,也许我必须以这种方式使用它,然后将数据移动到我自己的类结构中。
任何指导?
namespace client { namespace ast
{
///////////////////////////////////////////////////////////////////////////
// Our employee struct
///////////////////////////////////////////////////////////////////////////
struct employee
{
int age;
std::string surname;
std::string forename;
double salary;
};
using boost::fusion::operator<<;
}}
// We need to tell fusion about our employee struct
// to make it a first-class fusion citizen. This has to
// be in global scope.
BOOST_FUSION_ADAPT_STRUCT(
client::ast::employee,
(int, age)
(std::string, surname)
(std::string, forename)
(double, salary)
)
namespace client
{
///////////////////////////////////////////////////////////////////////////////
// Our employee parser
///////////////////////////////////////////////////////////////////////////////
namespace parser
{
namespace x3 = boost::spirit::x3;
namespace ascii = boost::spirit::x3::ascii;
using x3::int_;
using x3::lit;
using x3::double_;
using x3::lexeme;
using ascii::char_;
x3::rule<class employee, ast::employee> const employee = "employee";
auto const quoted_string = lexeme['"' >> +(char_ - '"') >> '"'];
auto const employee_def =
lit("employee")
>> '{'
>> int_ >> ','
>> quoted_string >> ','
>> quoted_string >> ','
>> double_
>> '}'
;
BOOST_SPIRIT_DEFINE(employee);
}
}
答案 0 :(得分:3)
struct
和class
¹之间没有区别。
除此之外,人们通常所说的是“我希望没有直接数据成员(”字段“)访问的课程。”
现在我可以直截了当地指出BOOST_FUSION_ADAPT_ADT
。这就是你要找的东西。
<强> 然而 强>
这意味着您已经为所有数据成员公开了setter。这是一个巨大的反模式²,因为它只会导致Quasi-Classes³。
考虑使用工厂函数(使用Phoenix调整它们来调用语义操作//但请参阅Boost Spirit: "Semantic actions are evil"?),或者确实有一个干净的AST表示,然后然后用于构建域对象图来自。
如果你负担不起(因为副本),你真的买不起Spirit V2 IMO。 Spirit旨在快速开发/改变(改变)语法,同时不会产生恶劣的代码。但是,如果你买不起副本,那么就可以手动翻译你的解析器(或转移到Spirit X3)
¹字面上唯一的区别是struct
默认情况下会公开所有成员,但您仍然可以使用private:
和protected:
²可能源于Java的PoJo或“Bean”的历史
³"Pseudo-Classes and Quasi-Classes Confuse Object-Oriented Programming"