この問題は、テンプレートのインスタンス化の深さと関係があります。を回避しinternal compiler error
、許容可能なコンパイル時間を得るために、パーサーにテンプレート ファイアウォールのようなものを実装する必要がありました。これはカスタム パーサーとして実装され、解析式でテンプレート化されていない関数を呼び出します。
struct OptimizedExpressionParser : x3::parser<OptimizedExpressionParser> {
using attribute_type = ast::Expression;
static bool const has_attribute = true;
//parse fnction, which calls "non-templated"-firewall function
template <typename Iter, typename Ctx, typename Attribute>
bool parse(Iter& iFirst, const Iter& iLast, const Ctx& iCtx, x3::unused_type, Attribute& oAttr) const {
ast::Expression a;
return parse(iFirst, iLast, iCtx, x3::unused, a);
}
//parse fnction, which calls "non-templated"-firewall function
template <typename Iter, typename Ctx>
bool parse(Iter& iFirst, const Iter& iLast, const Ctx& iCtx, x3::unused_type, ast::Expression& oAttr) const {
if (iFirst != iLast) {
return parse_expression(iFirst, iLast, oAttr);
}
return false;
}
private:
//"non-template"- parse function
//of cause this is a template function, but the parser isnt a template argument
template <typename Iter>
bool parse_expression(Iter& iFirst, const Iter& iLast, ast::Expression& oAst) const {
return x3::parse(iFirst, iLast, expression_impl, oAst);
}
};
このコードexpression_impl
では、古い「重い」式パーサーであり、新しい「ファイアウォール」式パーサーは次のとおりです。
auto const expression = OptimizedExpressionParser{};
別のパーサーで式を使用したい場合、または解析のためにパーサーのexpression
オブジェクトを使用するようになりましたOptimizedExpressionParser
。これにより、RAM の使用量、コンパイル時間、および結果のバイナリのサイズも減少します (テンプレート ファイアウォールなしでは約 1.6 Gb でした) 。
正直なところ、私はこの問題を自分で解決したことはありませんでした。アイデアとほとんどのコードはhereから来ています。与えられた例でうまくいくように少し変更しただけです。