使用带模板的访问者遍历boost :: variant类型

时间:2013-05-08 15:12:20

标签: c++ templates boost variant boost-variant

我有一个持久性类,如:

class Writer: private boost::noncopyable {
    template<typename T>
    struct Record {
        std::vector<T> _queued; // waiting to be persisted
        hsize_t _fileRows; // on disk
        DataSet _ds;
        ...
    };

    template<typename T>
    void write(Writer::Record<T>& rcrd) { ... }
    ...

用于保存类型如:

struct A {
    sockaddr_in udpAddr;
    ...
}

struct B {
    uint8_t id;
    ...
}

struct C { ... }
...

我无法更改上面的API,我想对这些异构类型执行批量操作。我在boost::variant之后使用their own tutorial取得了部分成功:

typedef boost::variant< Record<A>, Record<B>, Record<C>, ...> _types;
std::vector<_types> _records;

struct CloseRecordVisitor : public boost::static_visitor<> {
    template <typename T>
    void operator()(T& operand) const {
        assert(operand._queued.empty());
        operand._ds.close();
    }
}; // This seems to work -template argument is substituted with Record<A>, Record<B>,...

struct WriteRecordVisitor : public boost::static_visitor<> {
    template <typename T>
    void operator()(T& operand) const {
        Writer::write(operand);
    }
}; // This never compiles

然后,所有(许多)异构类型的批量操作只是简单地执行:

CloseRecordVisitor _closeRecordVisitor;
std::for_each(_records.begin(), _records.end(), boost::apply_visitor(_closeRecordVisitor));

WriteRecordVisitor _writeRecordVisitor;
std::for_each(_records.begin(), _records.end(), boost::apply_visitor(_writeRecordVisitor));

WriteRecordVisitor无法编译。错误是

No matching function to call ...template substitution failed. Cannot convert 'operand' (type Writer::Record<A>) to type 'Writer::Record<Record<A>>&'

显然看起来不对,但我无法弄清楚是什么导致了它。

我想让WriteRecordVisitor方法工作或者能够遍历向量(获取boost :: variant&lt; ...&gt;)并以某种方式(可能再次使用模板)使用boost :: get传递每个适当的元素(记录&lt; A&gt;,记录&lt; B&gt;,...)到Writer :: write(记录&lt; T&gt;)。

我还想避免为每种可能的异构类型定义访问者运算符,因为这会破坏简化首先使用异构容器的原始目标。

我在Linux 3.5.4 Fedora 17上使用gcc 4.7.2。感谢任何帮助 - 我在发布之前读过boost :: variant上的所有其他帖子。

0 个答案:

没有答案