I tried to compile my old code (json to struct parser) that use many template magic (mostly tuples), to give me possibility to describe parser commands like this:
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);
This code builds parser chains to unpack json (QJsonValue object from Qt library) to plain struct.
- Read "name" property, cast to QString (only non-empty, or fail elsewhere) that write to "name" property (QString);
- Read "name" property, cast to QString (only non-empty, or fail elsewhere) that write to "name" property (QString);
- If possible, read "submeshes", unlist (perform to every item from array), cast (every item) to non-empty QString and append (every item) to "submeshres" property (QList).
Than parse:
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"]}
Sometimes this code works perfect, but g++ 4.9 tries to build template in variations that is not used in my code.
Error:
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::*;
This error is raised only on first usages of Ops::cast
, Ops::write
(and on two more commands - one_of
and or_else
) in debug and release build configurations.
Ops
- namespace with parser operation. Ops::cast
returns object from _helpers::caster
template. This object stores pointer to cast function.
I have operator to work with cast helper:
template<...> ParserNode<%output_tuple_type%> operator >>(ParserNode<%input_tuple_type&>, _helpers::caster<From, To> cmd)
This operator append new command (cast
in this case) to parse chain and returns new node, but... I don't use Ops::packer
(that returns object from _helpers::packer
template) on lines with errors, so no need to build operator >>
for Ops::packer
for node with such tuple types. Each operator is written standalone, not in ParserNode
template class body, so I expect that g++
will build only needed combinations.
This line in Qt project file:
QMAKE_CXX=g++-4.8
Fixes the problem (g++ 4.8 can build my code), but this is like walk on crutches.
Can I set some additional g++ parameters (to QMAKE_CXXFLAGS
) to prevent building unused templates combinations? Don't want to rewrite this code, at least now...
Aucun commentaire:
Enregistrer un commentaire