
2013/2/21 Larry Evans <cppljevans@suddenlink.net>:
I haven't a clear idea how this would work because I assumed that the binary input stream would have to have something that 1st would be decoded into the tag for the variant. Then, if your variant visitor solution is used, some code (not shown) would create some default constructed value for the bounded type corresponding to that tag and then call the visitor.
All the above is just off the top of my head, but, as I said, I'm not real sure the variant visitor solution would work.
Could you provide more pseudo code to clarify.
Here is some more pseudo code, may be it will help you. #include <boost/variant.hpp> struct name_visitor: public boost::static_visitor<std::string> { template <class T> const std::string& opertor()(const T& val) const { return val.name; } // Specific visitor for Person std::string opertor()(const Person& val) const { return val.first_name + " " + val.second_name; } // Specific visitor for Something std::string opertor()(const Something& val) const { throw std::logic_error("Class Something has no name!"); } }; class EmployeePacket { typedef boost::variant<String, Double, Person, Something> variant_t; std::vector<variant_t> Items; EmployeePacket() { // copying variants is not as fast as copying pointers, // so it is better to reserve some space first Items.reserve(200); } void Decode(istream& Stream) { while (Stream) { switch (Stream.getc()) { case 'S': Items.push_back(String(Stream)); break; case 'D': Items.push_back(Double(Stream)); break; case 'P': Items.push_back(Person(Stream)); break; } } } double GetSalary(std::size_t index) const { // Will throw if at 'index' is not a Double type return boost::get<Double>(Items[index]).value; } std::string GetName(std::size_t index) const { return boost::apply_visitor(name_visitor(), Items[index]); } } // All the folloving classes must have a constructor that accepts an istream& class Double { string name; string units; // double decode_conversion_scale; // double decode_conversion_translate; // unsigned number_of_bits_used_to_encode // double scale_factor double value; void Decode(istream& Stream) // Will be called from constructor { Stream.read(&value, 8); value = value * decode_conversion_scale + decode_conversion_translate; } class String { string name; string value; void Decode(istream& Stream); // Will be called from constructor } class Person { string first_name; string second_name; void Decode(istream& Stream); // Will be called from constructor } class Something { /*string name; Has NO name! */ void Decode(istream& Stream); } Forgot to mention about disadvantages: * slower copy construction and copy assignment of variant types (compared to pointers) * all the types used in variant must be full (not just forward declared) If second disadvantage is 'too disadvantageous' for you, I can provide exactly the same example with boost::any instead of boost::variant -- Best regards, Antony Polukhin