Note that there are some explanatory texts on larger screens.

plurals
  1. POTraversing boost::variant types with Visitor that takes template
    text
    copied!<p>I've got a persistence class like:</p> <pre><code>class Writer: private boost::noncopyable { template&lt;typename T&gt; struct Record { std::vector&lt;T&gt; _queued; // waiting to be persisted hsize_t _fileRows; // on disk DataSet _ds; ... }; template&lt;typename T&gt; void write(Writer::Record&lt;T&gt;&amp; rcrd) { ... } ... </code></pre> <p>That is used to persist Types such as:</p> <pre><code>struct A { sockaddr_in udpAddr; ... } struct B { uint8_t id; ... } struct C { ... } ... </code></pre> <p>I can't change the APIs above and I want to perform bulk operations on these heterogeneous types. I'm using <a href="http://www.boost.org/doc/libs/1_53_0/doc/html/variant.html" rel="nofollow">boost::variant</a> with partial success, following <a href="http://www.boost.org/doc/libs/1_53_0/doc/html/variant/tutorial.html" rel="nofollow">their own tutorial</a>:</p> <pre><code>typedef boost::variant&lt; Record&lt;A&gt;, Record&lt;B&gt;, Record&lt;C&gt;, ...&gt; _types; std::vector&lt;_types&gt; _records; struct CloseRecordVisitor : public boost::static_visitor&lt;&gt; { template &lt;typename T&gt; void operator()(T&amp; operand) const { assert(operand._queued.empty()); operand._ds.close(); } }; // This seems to work -template argument is substituted with Record&lt;A&gt;, Record&lt;B&gt;,... struct WriteRecordVisitor : public boost::static_visitor&lt;&gt; { template &lt;typename T&gt; void operator()(T&amp; operand) const { Writer::write(operand); } }; // This never compiles </code></pre> <p>Then the bulk operations across all the (many) heterogeneous types was meant to do simply:</p> <pre><code>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)); </code></pre> <p>WriteRecordVisitor doesn't compile. Error is </p> <pre><code>No matching function to call ...template substitution failed. Cannot convert 'operand' (type Writer::Record&lt;A&gt;) to type 'Writer::Record&lt;Record&lt;A&gt;&gt;&amp;' </code></pre> <p>Which evidently looks wrong but I can't figure out what's causing it.</p> <p>I'd like to either have the WriteRecordVisitor approach working or be able to iterate through the vector (obtaining boost::variant&lt;...&gt;) and somehow (template again, likely) use boost::get to pass each appropriate element (Record&lt;A&gt;, Record&lt;B&gt;, ...) to Writer::write(Record&lt;T&gt;).</p> <p>I'd also like to avoid defining a visitor operator for each possible heterogeneous type, as that would defeat the original goal of simplifying using an heterogeneous container in the 1st place.</p> <p>I'm using gcc 4.7.2 on Linux 3.5.4 Fedora 17. Any help is appreciated -I did read all the other posts on boost::variant before posting.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload