Boost::variant成员子集的另一个Boost::variant

boost::variant members subset of another boost::variant

本文关键字:Boost variant 另一个 成员 子集      更新时间:2023-10-16

我正在使用一个相当笨拙的c接口来存储集合。类LowLevelStorer表示我为这个接口编写的包装器。Storer类是与Data相关的高级类。它进行缓存并将数据捆绑到只有LowLevelStorer才知道的更复杂的数据类型中。我的代码的其余部分只关注Data,而不了解LowLevelData

在下面的示例代码中,我希望Data变体中的成员包含在LowLevelData变体中。有没有一种方法可以说明我是怎么做的?

我真的不明白的是为什么下面的代码编译,事实上,为什么它实际上是正确的工作。也就是说,void operator()(const SimplePath&, const Data& data) const接受一个Data引用,但在调用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;
}

我怀疑,当您提供参数作为另一个参数时,它使用一个变量的原因是因为您的两个变量具有所有公共类型,这使得您的变量可以相互转换。

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