0

我尝试编译使用许多模板魔术(主要是元组)的旧代码(json to struct parser),以便我可以描述如下解析器命令:

auto mesh_parser = TupleParser<Mesh&>::create("Mesh list parser");
mesh_parser >> Ops::read("name") >> Ops::cast(&stringNotEmpty) >> Ops::write(&Mesh::name);
mesh_parser >> Ops::read("file") >> Ops::cast(&stringNotEmpty) >> Ops::write(&Mesh::file);
mesh_parser >> Ops::optional() >> Ops::read("submeshes") >> Ops::unlist() >> Ops::cast(&stringNotEmpty) >> Ops::write(&Mesh::submeshes);

此代码构建解析器链以将 json(Qt 库中的 QJsonValue 对象)解压缩为普通结构。

  • 读取“name”属性,转换为写入“name”属性(QString)的QString(仅非空,或在其他地方失败);
  • 读取“name”属性,转换为写入“name”属性(QString)的QString(仅非空,或在其他地方失败);
  • 如果可能,请阅读“submeshes”、unlist(对数组中的每个项目执行)、将(每个项目)转换为非空 QString 并将(每个项目)附加到“submeshres”属性(QList)。

比解析:

Mesh output;
mesh_list_parser->parse(output, json_value);

// where json_value is QJsonValue with something like that:
// {"name":"foo","file":"bar.json","submeshes":["foo","bar","baz"]}

有时这段代码可以完美运行,但 g++ 4.9 尝试在我的代码中未使用的变体中构建模板。

错误:

In file included from ../../Project/src/Render/meshmanager.cpp:4:0:
../../Project/src/Parse/tupleparser.h: In instantiation of 'struct _helpers::packer<Mesh&, QJsonValue>':
../../Project/src/Render/meshmanager.cpp:69:88:   required from here
../../Project/src/Parse/tupleparser.h:1144:38: error: creating pointer to member reference type 'Mesh&'
    using Field = FieldType Unref::*;

仅在调试和发布构建配置中首次使用Ops::cast, Ops::write(以及另外两个命令 -one_of和)时才会引发此错误。or_else

Ops- 带有解析器操作的命名空间。从模板Ops::cast返回对象。_helpers::caster该对象存储指向转换函数的指针。

我有操作员与演员表助手一起工作:

template<...> ParserNode<%output_tuple_type%> operator >>(ParserNode<%input_tuple_type&>, _helpers::caster<From, To> cmd)

此运算符附加新命令(cast在本例中)以解析链并返回新节点,但是...我不在有错误的行上使用Ops::packer(从_helpers::packer模板返回对象),因此无需operator >>Ops::packer具有此类元组的节点构建类型。每个运算符都是独立编写的,而不是在ParserNode模板类主体中,所以我希望它g++只会构建需要的组合。


Qt 项目文件中的这一行:

QMAKE_CXX=g++-4.8

修复了问题(g++ 4.8 可以构建我的代码),但这就像拄着拐杖走路。

我可以设置一些额外的 g++ 参数 (to QMAKE_CXXFLAGS) 以防止构建未使用的模板组合吗?不想重写这段代码,至少现在......

4

0 回答 0