4

std::vector<boost::variant<..>>他のオブジェクトによって提供される装飾を使用してデシリアライズする必要があります。

「装飾」によって可能になることの 1 つは、ベクター内の空のエントリです。私は実際の実装でレンガの壁にぶつかりました。しかし、私はそれをシュリンクラップすることに成功しました。コンパイルするコード:

#include <string>
#include <boost/spirit/include/karma.hpp>
#include <boost/variant.hpp>
#include <boost/cstdint.hpp>

namespace karma = boost::spirit::karma;

typedef boost::variant<boost::int32_t, boost::int64_t> custom_variant;

int main()
{
    using karma::generate;

    custom_variant v;

    std::string temp;

    std::back_insert_iterator<std::string> x(temp);

    std::cout << v;

    karma::generate(x, karma::auto_, v);
}

必要な概念とともに、「未定義」タイプを実装しようとする問題のある変更。

#include <string>
#include <boost/spirit/include/karma.hpp>
#include <boost/variant.hpp>
#include <boost/cstdint.hpp>

namespace karma = boost::spirit::karma;

struct undefined{};

std::ostream & operator<<(std::ostream & out, undefined const & undefined)
{
    return out;
}

typedef boost::variant<undefined,boost::int32_t, boost::int64_t> custom_variant;

int main()
{
    using karma::generate;

    custom_variant v;

    std::string temp;

    std::back_insert_iterator<std::string> x(temp);

    std::cout << v;

    karma::generate(x, karma::auto_, v);
}

karma::generateステップをコメントアウトするstd::coutと、有効な式 (Boost::variant OutputStreamable) になります。Spirit では、ジェネレーターにはOutputStreamable(spirit::karma ) である型を指定する必要があり、型をノーオペレーションとして作成したため、OutputStreamable上記のバリアントはそうである必要があります。OutputStreamableundefinedOutputStreamable

何を与える?:(

2 レベル以上のテンプレートの間接化を持つライブラリを使用する場合、C++ のテンプレート メカニズムに価値があるかどうか、私は本当に疑問を持ち始めています。おそらく私はまっすぐに戻る必要があります-c.

編集1:

わかりました、Clangは私に賢明なfirstエラーを与えました...

error: no type named 'properties' in 'boost::spirit::karma::no_auto_mapping_exists'

ここで、undefined を no-op としてマップして、クリーンな変換を行う方法を理解する必要があります。このスピリットのドキュメント エントリ(および具体的にはこれ) は、私が調査する必要があることを説明しています。スピリットによって提供される一般的な未定義のタイプ、またはブーストで定義されたタイプはありますか?そのスピリットはすでに no-op としてマップされていますか?

編集2:

std::vector<boost::optional<boost::variant<..>>>Spirit はそれらに型推論を提供するので、かなり魅力的に見え始めています。

4

1 に答える 1

3

spirit::unused_typeすでにスピリットに「知られている」ため、その目的で使用することをお勧めしますoperator<<()(ただし、他のタイプでも可能です)-そもそもカルマにその演算子が本当に必要なわけではありません。

さらに、create_generator(ご想像のとおり)次の専門分野を提供する必要があります。

namespace boost { namespace spirit { namespace traits
{
    template <>
    struct create_generator<spirit::unused_type>
    {
        typedef spirit::karma::eps_type type;

        static type call()
        {
            return spirit::karma::eps;
        }
    };
}}}

にマップunused_typeされkarma::epsます。epsこれは、常に成功しながら、何も生成せずに属性を食べるため、まさに必要なもののようです。この方法を使用する場合は、使用する必要はありませんoptional<>

于 2011-04-14T17:07:22.107 に答える