У меня есть класс постоянства, как:
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 выше, и я хочу выполнять массовые операции с этими гетерогенными типами. я использую повышение :: вариант с частичным успехом, следуя их собственный учебник:
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 :: variable<…>) и как-то (снова шаблон, скорее всего) использовать boost :: get для передачи каждого соответствующего элемента (запись<>, Запись<В>, …) Писателю :: запись (Запись)<T>).
Я также хотел бы избежать определения оператора посетителя для каждого возможного гетерогенного типа, так как это противоречило бы первоначальной цели упрощения использования гетерогенного контейнера в первую очередь.
Я использую gcc 4.7.2 в Linux 3.5.4 Fedora 17. Любая помощь приветствуется — я прочитал все остальные посты на boost :: варианте перед публикацией.
Задача ещё не решена.
Других решений пока нет …