次のような永続性クラスがあります。
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を部分的に成功させて使用しています。
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<...> を取得)、何らかの方法で (おそらくテンプレートを使用して) boost::get を使用して、適切な各要素を渡したいと思います ( Record<A>, Record<B>, ...) を Writer::write(Record<T>) に変換します。
また、考えられる異種の型ごとにビジター オペレータを定義することも避けたいと思います。これは、最初に異種のコンテナを使用して単純化するという当初の目標に反するからです。
Linux 3.5.4 Fedora 17 で gcc 4.7.2 を使用しています。