我正在使用一个比较尴尬的C接口来存储集合。类LowLevelStorer代表我为此接口编写的包装器。 Storer类是与Data有关的高级类。它确实进行缓存,并将数据捆绑为仅LowLevelStorer已知的更复杂的数据类型。我其余的代码仅使用Data本身而不了解LowLevelData

在下面的示例代码中,我希望Data变体中的成员包含在LowLevelData变体中。有没有办法指定其他方式,例如我是如何做到的?

我真正不明白的是,为什么下面的代码可以编译,实际上,为什么它可以正常工作。也就是说,void operator()(const SimplePath&, const Data& data) const接受数据引用,但是在调用void operator()(const LowLevelData& data) const时似乎可以正确地将其转换为LowLevelData对象。怎么会这样?

关于我的数据对象,在幕后有很多副本吗?

#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;
}

最佳答案

我怀疑,当您提供参数时将一个变体作为另一个变体,之所以这样,是因为两个变体的所有类型都相同,这使得您的变体可以相互转换。

我认为只使用所有三种类型的一个变体并完全跳过另一种是完全可以的,因为看到第二种仅仅是第一种类型的子集。

09-10 00:17
查看更多