Я попытался скомпилировать мой старый код (от json до 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 (объект QJsonValue из библиотеки Qt) в обычную структуру.
Чем разбирать:
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
шаблон. Этот объект хранит указатель на функцию приведения.
У меня есть оператор для работы с Cast Helper:
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 ++ (для QMAKE_CXXFLAGS
) чтобы не создавать неиспользуемые шаблоны комбинаций? Не хочу переписывать этот код, по крайней мере сейчас …
Задача ещё не решена.
Других решений пока нет …