質問は一番下に太字で示され、問題は最後に蒸留コードの断片によって要約されています。
型システム (型システムは型から文字列へと型から文字列へ) を単一のコンポーネント (Lakos で定義されている) に統合しようとしています。これを達成するために、、、boost::array
およびboost::variant
を使用しています。boost::mpl
型のパーサーとジェネレーターのルールをバリアントに統合したいと考えています。未定義の型、int4 (下記参照) 型、および int8 型があります。バリアントは次のように読み取りますvariant<undefined, int4,int8>
。
int4 の特徴:
struct rbl_int4_parser_rule_definition
{
typedef boost::spirit::qi::rule<std::string::iterator, rbl_int4()> rule_type;
boost::spirit::qi::int_parser<rbl_int4> parser_int32_t;
rule_type rule;
rbl_int4_parser_rule_definition()
{
rule.name("rbl int4 rule");
rule = parser_int32_t;
}
};
template<>
struct rbl_type_parser_rule<rbl_int4>
{
typedef rbl_int4_parser_rule_definition string_parser;
};
上記のバリアントは未定義として開始し、その後ルールを初期化します。問題が発生し、50 ページのエラーが発生しましたが、最終的に追跡することができました.Variant はoperator=
割り当て中に使用され、aboost::spirit::qi::int_parser<>
は別のもの (operator=) に割り当てることができません。
対照的に、未定義の型に問題はありません。
struct rbl_undefined_parser_rule_definition
{
typedef boost::spirit::qi::rule<std::string::iterator, void()> rule_type;
rule_type rule;
rbl_undefined_parser_rule_definition()
{
rule.name("undefined parse rule");
rule = boost::spirit::qi::eps;
}
};
template<>
struct rbl_type_parser_rule<rbl_undefined>
{
typedef rbl_undefined_parser_rule_definition string_parser;
};
問題の抽出:
#include <string>
#include <boost/spirit/include/qi.hpp>
#include <boost/variant.hpp>
#include <boost/cstdint.hpp>
typedef boost::spirit::qi::rule<std::string::iterator,void()> r1;
typedef boost::spirit::qi::rule<std::string::iterator,int()> r2;
typedef boost::variant<r1,r2> v;
int main()
{
/*
problematic
boost::spirit::qi::int_parser<int32_t> t2;
boost::spirit::qi::int_parser<int32_t> t1;
t1 = t2;
*/
//unproblematic
r1 r1_;
r2 r2_;
r1_ = r2_;
v v_;
// THIS is what I need to do.
v_ = r2();
}
具体的なパーサーとルールの間にはセマンティック ギャップがあります。私の脳は現在喫煙しているので、実用主義について考えるつもりはありません.私の質問は、どうすればこの問題を解決できるでしょうか? この問題を解決するための 3 つのアプローチを考えることができます。
one:静的関数メンバー:
struct rbl_int4_parser_rule_definition
{
typedef boost::spirit::qi::rule<std::string::iterator, rbl_int4()> rule_type;
//boost::spirit::qi::int_parser<rbl_int4> parser_int32_t;
rule_type rule;
rbl_int4_parser_rule_definition()
{
static boost::spirit::qi::int_parser<rbl_int4> parser_int32_t;
rule.name("rbl int4 rule");
rule = parser_int32_t;
}
};
アプローチ1はスレッドセーフコードを防ぐと思いますか? ?
2:統合パーサーは shared_ptr にラップされます。私が型付けシステムの TMP に悩まされている理由は 2 つあります。ポインターを使用すると、最初の理由が無効になります。
3: operator= は no-op として定義されています。lhs
バリアントは、割り当て前にデフォルトで構築されることを保証します。
編集: オプション3が最も理にかなっていると思います(operator =はノーオペレーションです)。ルール コンテナが作成されると変更されず、タイプのルール トレイトをそのオフセットに強制的に割り当てるだけです。