0

コレクションを保存するためのかなり扱いにくいcインターフェイスを使用しています。このクラスLowLevelStorerは、このインターフェイス用に記述したラッパーを表します。このStorerクラスは、 に関係する高レベルのクラスDataです。キャッシングを行い、データを だけが知っているより複雑なデータ型にバンドルしますLowLevelStorer。私のコードの残りの部分はDataLowLevelData.

以下のコード例では、バリアントのメンバーがDataバリアントに含まれるようにしLowLevelDataます。これを他の方法で指定する方法はありますか?

私が本当に理解していないのは、以下のコードがコンパイルされる理由と、実際に実際に正しく動作する理由です。つまりvoid operator()(const SimplePath&, const Data& data) const、 Data 参照を取りますが、呼び出し時に LowLevelData オブジェクトに正しく変換しているようvoid operator()(const LowLevelData& data) constです。どうすればいいの?

データ オブジェクトに関して、舞台裏で多くのコピーが行われていますか?

#include "boost/variant.hpp"
#include "boost/variant/apply_visitor.hpp"
#include <vector>

class Complex{};
typedef boost::variant< std::vector<Complex>, std::vector<int>, std::vector<std::string> > LowLevelData;

class LowLevelStorer
{
public:
    LowLevelStorer(): _storeVisitor(StoreVisitor()){}

    void operator()(const LowLevelData& data) const 
    {
        boost::apply_visitor(_storeVisitor, data);
    }

private:
    class StoreVisitor: public boost::static_visitor<>
    {
    public:
        void operator()(const std::vector<Complex>&) const {}

        void operator()(const std::vector<int>& i) const {}

        void operator()(const std::vector<std::string>&) const {}
    };

    StoreVisitor _storeVisitor;
};


struct SimplePath{};
struct BundlePath{};
typedef boost::variant< SimplePath, BundlePath > Path;

typedef boost::variant< std::vector<std::string>, std::vector<int> > Data;

class Storer
{
public:
    Storer(const LowLevelStorer& lowLevelStorer): _converter(Converter(lowLevelStorer)){}

    void operator()(const Path& path, const Data& data) const 
    {
        boost::apply_visitor(_converter, path, data);
    }

private:
    class Converter: public boost::static_visitor<>
    {
    public:
        Converter(const LowLevelStorer& lowLevelStorer): _lowLevelStorer(lowLevelStorer){}

        void operator()(const SimplePath&, const Data& data) const {
            _lowLevelStorer(data);
        }

        void operator()(const BundlePath&, const Data& data) const {
            _lowLevelStorer(std::vector<Complex>());
        }
    private:
        const LowLevelStorer _lowLevelStorer;
    };

    const Converter _converter;
};

int main()
{
    Storer storer((LowLevelStorer()));
    std::vector<int> v;
    v.push_back(13);
    storer(Path(SimplePath()),v);

    return 0;
}
4

1 に答える 1

2

パラメーターを指定したときに一方のバリアントを別のバリアントとして使用する理由は、両方のバリアントにすべての型が共通しているため、バリアントを相互に変換できるためです。

1 つのバリアントを 3 つのタイプすべてで使用し、もう 1 つのバリアントを完全にスキップしてもまったく問題ないと思います。2 番目のバリアントは最初のタイプのサブセットにすぎません。

于 2013-03-11T09:52:22.390 に答える