boost::variant and printing methods of elements in vector - c++

std::vector< boost::variant<std::string, int> > vec;
std::string s1("abacus");
int i1 = 42;
vec.push_back(s1);
vec.push_back(i1);
std::cout << vec.at(0).size() << "\n";
when I try to run this code, I get the following error:
main.cpp:68: error: ‘class boost::variant<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, int, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_>’ has no member named ‘size’
make: *** [main.o] Error 1
however, being a string it should have a size() method. I'm not sure what is going wrong. note that replacing the last line with:
std::cout << vec.at(0) << "\n";
will print "abacus", as expected.

being a string it should have a size() method
It’s not a string – it’s a variant. You first need to tell the compiler that you know there’s a string inside – i.e. retrieve it using boost::get<std::string>(vec[0]).
Be sure to read the Boost.Variant tutorial.

You need to get the first type of this variant (which is the string), the class boost::variant which you are accessing with vector::at() has no method called size(), try something like::
boost::get<0>(vec.at(0)).size(); // I think that's the syntax....

Related

variant pixel buffer to vector using boost::apply_visitor

I am trying to convert variablepixelbuffer.vbuffer() to a vector of double values using apply_visitor in boost.
I came with this piece of code till now :
struct GetVector : public boost::static_visitor<std::vector<double>>
{
//values will be returned in a pair. double is
// used since it can contain the value for any pixel type
typedef std::vector<double> result_type;
template<typename T
void myfunction (const T& i) { // function:
result_type.push_back(static_cast<double>(*i));
}
template<typename T>
result_type
operator() (const T& v)
{
typedef typename T::element_type::value_type value_type;
std::for_each (v->data(), v->data() + v->num_elements(), myfunction);
return result_type;
}
};
/* pixel-example-start */
void
readPixelData(const FormatReader& reader,
std::ostream& stream,int x,int y,int w,int h)
{
// Change the current series to this index
reader.setSeries(0);
// Get total number of planes (for this image index)
dimension_size_type pc = reader.getImageCount();
// Pixel buffer
VariantPixelBuffer buf;
dimension_size_type xd = x;
dimension_size_type yd = y;
dimension_size_type wd = w;
dimension_size_type hd = h;
// Loop over planes (for this image index)
for (dimension_size_type p = 0 ; p < pc; p++)
{
// Read the entire plane into the pixel buffer.
reader.openBytes(p, buf,xd,yd,wd,hd);
}
GetVector visitor;
GetVector::result_type result = boost::apply_visitor(visitor, buf.vbuffer());
}
But i am getting some long errors, and some piece of it are
/usr/include/boost/variant/detail/apply_visitor_unary.hpp:60:43:
required from ‘typename Visitor::result_type
boost::apply_visitor(Visitor&, Visitable&) [with Visitor =
MinMaxVisitor; Visitable =
boost::variant >,
boost::mpl::v_item >,
boost::mpl::v_item
, boost::mpl::v_item >,
boost::mpl::v_item >,
boost::mpl::v_item >,
boost::mpl::v_item
, boost::mpl::v_item
, boost::mpl::v_item
, boost::mpl::v_item
, boost::mpl::v_item
, boost::mpl::vector0, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1> >, boost::detail::variant::void_,
boost::detail::variant::void_, boost::detail::variant::void_,
boost::detail::variant::void_, boost::detail::variant::void_,
boost::detail::variant::void_, boost::detail::variant::void_,
boost::detail::variant::void_, boost::detail::variant::void_,
boost::detail::variant::void_, boost::detail::variant::void_,
boost::detail::variant::void_, boost::detail::variant::void_,
boost::detail::variant::void_, boost::detail::variant::void_,
boost::detail::variant::void_, boost::detail::variant::void_,
boost::detail::variant::void_, boost::detail::variant::void_,
boost::detail::variant::void_, boost::detail::variant::void_,
boost::detail::variant::void_, boost::detail::variant::void_,
boost::detail::variant::void_, boost::detail::variant::void_,
boost::detail::variant::void_, boost::detail::variant::void_,
boost::detail::variant::void_, boost::detail::variant::void_,
boost::detail::variant::void_, boost::detail::variant::void_,
boost::detail::variant::void_, boost::detail::variant::void_,
boost::detail::variant::void_, boost::detail::variant::void_,
boost::detail::variant::void_, boost::detail::variant::void_,
boost::detail::variant::void_, boost::detail::variant::void_>;
typename Visitor::result_type = std::vector >]’ read_subimage.C:82:85: required from here
/usr/include/c++/4.8/bits/stl_algo.h:4417:14: error: must use ‘.’ or
‘->’ to call pointer-to-member function in ‘__f (...)’, e.g. ‘(...
->* __f) (...)’
How can i reslove this, I need to get the pixel buffer data into vector .

deal with boost variant and boost function

I would like a vector to hold differents kind of boost::function, so, I tried a variant :
#include <boost/variant.hpp>
#include <boost/bind.hpp>
#include <boost/function.hpp>
#include <vector>
void a(int, int)
{}
void b()
{}
int main(int argc, char **argv)
{
typedef boost::variant<boost::function0<void>, boost::function2<void, int, int>> v;
std::vector<v> c;
c.push_back(boost::bind(&a, _1, _2));
c.push_back(boost::bind(&b));
auto& function = boost::get<boost::function2<void, int, int>>(c[0]);
function(4, 5);
}
But I've this error :
/usr/local/include/boost/variant/variant.hpp:1515:28: error: call to member function 'initialize' is ambiguous
initializer::initialize(
~~~~~~~~~~~~~^~~~~~~~~~
/usr/local/include/boost/variant/variant.hpp:1692:9: note: in instantiation of function template specialization 'boost::variant<boost::function0<void>, boost::function2<void, int, int>, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_>::convert_construct<boost::_bi::bind_t<void, void (*)(int, int), boost::_bi::list2<boost::arg<1>, boost::arg<2> > > >' requested here
convert_construct( detail::variant::move(operand), 1L);
^
I didn't find any help to deal with theses error
(and other compiler output)
https://ideone.com/QEdlyF
Thanks !
The constructor for Boost Function is pretty liberal in what it can accept. This results in there being no "best" constructor amongst the elements types of the variant.
You'll have to explicitly cast.
Then again, it's probably even easier to just hide the knowledge about types alltogether (since the helpful parts are ambiguous anyways) and use Boost Any.

How to use Boost Spirit with variant with more than 20 types?

I'm parsing a quite complex grammar with Boost Spirit and I'm facing a problem with a variant that have more than 20 types (21 here):
namespace eddic { namespace ast {
typedef boost::mpl::vector<
Integer,
IntegerSuffix,
Float,
Litteral,
VariableValue,
DereferenceValue,
Expression,
Unary,
Null,
True,
False,
ArrayValue,
FunctionCall,
MemberFunctionCall,
Cast,
BuiltinOperator,
Assignment,
SuffixOperation,
PrefixOperation,
Ternary
> types_initial;
typedef boost::mpl::push_back<types_initial, New>::type types;
typedef boost::make_variant_over<types>::type Value;
}}
Boost Spirit does not recognize the last type (eddic::ast::New) added with push_back. When I parse something that have this element, it fails with this error:
eddic: /usr/include/boost/variant/detail/visitation_impl.hpp:264:
typename Visitor::result_type
boost::detail::variant::visitation_impl(int, int, Visitor&, VoidPtrCV,
mpl_::false_, NoBackupFlag, Which*, step0*) [with Which =
mpl_::int_<0>; step0 =
boost::detail::variant::visitation_impl_step,
boost::mpl::v_item,
boost::mpl::v_item,
boost::mpl::v_item,
boost::mpl::v_item,
boost::mpl::v_item,
boost::mpl::v_item,
boost::mpl::v_item,
boost::mpl::v_item,
boost::mpl::v_item,
boost::mpl::v_item,
boost::mpl::v_item,
boost::mpl::v_item,
boost::mpl::v_item,
0>, 0>, 0>, 0>, 0>, 0>, 0>, 0>, 0>, 0>, 0>, 0>, 0>, 0>, 0>, 0>, 0>,
0>, 0>, 0>, 0>, 0l>,
boost::mpl::v_iter,
boost::mpl::v_item,
boost::mpl::v_item,
boost::mpl::v_item,
boost::mpl::v_item,
boost::mpl::v_item,
boost::mpl::v_item,
boost::mpl::v_item,
boost::mpl::v_item,
boost::mpl::v_item,
boost::mpl::v_item,
boost::mpl::v_item,
boost::mpl::v_item,
boost::mpl::v_item,
0>, 0>, 0>, 0>, 0>, 0>, 0>, 0>, 0>, 0>, 0>, 0>, 0>, 0>, 0>, 0>, 0>,
0>, 0>, 0>, 0>, 21l> >; Visitor =
boost::variant, boost::mpl::vector,
eddic::ast::Deferred,
eddic::ast::Deferred, eddic::ast::Null,
eddic::ast::True, eddic::ast::False,
eddic::ast::Deferred,
eddic::ast::Deferred,
eddic::ast::Deferred,
eddic::ast::Deferred,
eddic::ast::Deferred,
eddic::ast::Deferred,
eddic::ast::Deferred,
eddic::ast::Deferred,
eddic::ast::Deferred >, 0> >,
boost::detail::variant::void_, boost::detail::variant::void_,
boost::detail::variant::void_, boost::detail::variant::void_,
boost::detail::variant::void_, boost::detail::variant::void_,
boost::detail::variant::void_, boost::detail::variant::void_,
boost::detail::variant::void_, boost::detail::variant::void_,
boost::detail::variant::void_, boost::detail::variant::void_,
boost::detail::variant::void_, boost::detail::variant::void_,
boost::detail::variant::void_, boost::detail::variant::void_,
boost::detail::variant::void_, boost::detail::variant::void_,
boost::detail::variant::void_>::assigner; VoidPtrCV = const void*;
NoBackupFlag =
boost::variant, boost::mpl::vector,
eddic::ast::Deferred,
eddic::ast::Deferred, eddic::ast::Null,
eddic::ast::True, eddic::ast::False,
eddic::ast::Deferred,
eddic::ast::Deferred,
eddic::ast::Deferred,
eddic::ast::Deferred,
eddic::ast::Deferred,
eddic::ast::Deferred,
eddic::ast::Deferred,
eddic::ast::Deferred,
eddic::ast::Deferred >, 0> >,
boost::detail::variant::void_, boost::detail::variant::void_,
boost::detail::variant::void_, boost::detail::variant::void_,
boost::detail::variant::void_, boost::detail::variant::void_,
boost::detail::variant::void_, boost::detail::variant::void_,
boost::detail::variant::void_, boost::detail::variant::void_,
boost::detail::variant::void_, boost::detail::variant::void_,
boost::detail::variant::void_, boost::detail::variant::void_,
boost::detail::variant::void_, boost::detail::variant::void_,
boost::detail::variant::void_, boost::detail::variant::void_,
boost::detail::variant::void_>::has_fallback_type_; typename
Visitor::result_type = void; mpl_::false_ = mpl_::bool_]:
Assertion `!"Boost.Variant internal error: 'which' out of range."'
failed.
If I swap two elements (Ternary and New for example), New is correctly recognized, but not Ternary. It is only the last element that fails.
I already tried using push_front or vector21, but it doesn't change anything, it's always the last element that have problem. In my opinion it comes from the fact that Spirit uses a variant internally before copying it to my variant_over type.
Is there a workaround to this problem ?
I could probably reduce the number to 20, but the problem is that I will certainly have more than that in the future.
Thanks a lot for any idea
Define BOOST_MPL_LIMIT_VECTOR_SIZE to whatever new limit you want, but going this high is usually a hint at design problems so it might be worth to give it some consideration.

boost::variant linker error with gcc

I am going a bit nuts trying to figure out why the following won't compile:
#include <iostream>
#include <array>
#include <boost/variant.hpp>
#include <forward_list>
typedef unsigned long long very_long;
typedef boost::variant< int, std::string > variants_type;
typedef std::array< variants_type, 5 > row_type;
typedef std::forward_list<row_type> rows_holder_type;
int main() {
rows_holder_type rows;
row_type row_data;
row_data[0] = 0;
row_data[1] = 0;
row_data[2] = 0;
row_data[3] = 0;
row_data[4] = 0;
rows.push_front(row_data);
}
This is the compiler error I am getting:
/usr/include/testing/test_code.o||In function 'std::array<boost::variant<int, std::basic_string<char, std::char_traits<char>, std::allocator<char> >, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_>, 5ul>::array(std::array<boost::variant<int, std::basic_string<char, std::char_traits<char>, std::allocator<char> >, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_>, 5ul> const&)':|
store.cpp:(.text._ZNSt5arrayIN5boost7variantIiSsNS0_6detail7variant5void_ES4_S4_S4_S4_S4_S4_S4_S4_S4_S4_S4_S4_S4_S4_S4_S4_S4_EELm5EEC2ERKS6_[_ZNSt5arrayIN5boost7variantIiSsNS0_6detail7variant5void_ES4_S4_S4_S4_S4_S4_S4_S4_S4_S4_S4_S4_S4_S4_S4_S4_S4_EELm5EEC5ERKS6_]+0x31)||undefined reference to 'boost::variant<int, std::basic_string<char, std::char_traits<char>, std::allocator<char> >, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_>::variant(boost::variant<int, std::basic_string<char, std::char_traits<char>, std::allocator<char> >, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_> const&)'|
||=== Build finished: 1 errors, 0 warnings ===|
If I replace:
typedef boost::variant< int, std::string > variants_type;
with:
typedef boost::any variants_type;
The code compiles, but I do not want to use boost::any for performance reasons.
I tested your code with MSVC and gcc 4.7.0. MSVC compiles and links the code fine (of course with #include <string>), but gcc gives a linker error on the last line rows.push_front(row_data);. If you comment that line out, gcc accepts the code. I see no reason why gcc gives a linker error and am concluding that it is a bug with gcc. One workaround on gcc would be to change std::array to std::vector.
(From the error message I assume you are using Code::Blocks with gcc)
I've eliminated extra code and the following example still gives the linker error:
#include <boost/variant.hpp>
#include <array>
int main()
{
std::array<boost::variant<int, double>, 5> row_type1;
std::array<boost::variant<int, double>, 5> row_type2 = row_type1;
}
You're missing #include <string>; other than that your code is fine.

build error with boost spirit grammar (boost 1.43 and g++ 4.4.1) part II

I'm having issues getting a small spirit/qi grammar to compile. i am using boost 1.43 and g++ 4.4.1.
the input grammar header:
the build error seems to be pointing to the definition of the 'instruction' rule, maybe it is the '[sp::_val = sp::_1]' that somehow brokes it but this is more or less based on what the spirit documentation tutorials are doing with the xml node parser
inputGrammar.h
#include <boost/config/warning_disable.hpp>
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix_core.hpp>
#include <boost/spirit/include/phoenix_operator.hpp>
#include <boost/spirit/include/phoenix_fusion.hpp>
#include <boost/spirit/include/phoenix_stl.hpp>
#include <boost/fusion/include/adapt_struct.hpp>
#include <boost/variant/recursive_variant.hpp>
#include <boost/foreach.hpp>
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
namespace sp = boost::spirit;
namespace qi = boost::spirit::qi;
using namespace boost::spirit::ascii;
//using namespace boost::spirit::arg_names;
namespace fusion = boost::fusion;
namespace phoenix = boost::phoenix;
using phoenix::at_c;
using phoenix::push_back;
template< typename Iterator , typename ExpressionAST >
struct InputGrammar : qi::grammar<Iterator, ExpressionAST(), space_type> {
InputGrammar() : InputGrammar::base_type( block ) {
tag = sp::lexeme[+(alpha) [sp::_val += sp::_1]];//[+(char_ - '<') [_val += _1]];
block = sp::lit("block") [ at_c<0>(sp::_val) = sp::_1]
>> "(" >> *instruction[ push_back( at_c<1>(sp::_val) , sp::_1 ) ]
>> ")";
command = tag [ at_c<0>(sp::_val) = sp::_1]
>> "(" >> *instruction [ push_back( at_c<1>(sp::_val) , sp::_1 )]
>> ")";
instruction = ( command | tag ) [sp::_val = sp::_1]; //build error seems to be happening here
}
qi::rule< Iterator , std::string() , space_type > tag;
qi::rule< Iterator , ExpressionAST() , space_type > block;
qi::rule< Iterator , ExpressionAST() , space_type > function_def;
qi::rule< Iterator , ExpressionAST() , space_type > command;
qi::rule< Iterator , ExpressionAST() , space_type > instruction;
};
the test build program:
#include <iostream>
#include <string>
#include <vector>
using namespace std;
//my grammar
#include <InputGrammar.h>
struct MockExpressionNode {
std::string name;
std::vector< MockExpressionNode > operands;
typedef std::vector< MockExpressionNode >::iterator iterator;
typedef std::vector< MockExpressionNode >::const_iterator const_iterator;
iterator begin() { return operands.begin(); }
const_iterator begin() const { return operands.begin(); }
iterator end() { return operands.end(); }
const_iterator end() const { return operands.end(); }
bool is_leaf() const {
return ( operands.begin() == operands.end() );
}
};
BOOST_FUSION_ADAPT_STRUCT(
MockExpressionNode,
(std::string, name)
(std::vector<MockExpressionNode>, operands)
)
int const tabsize = 4;
void tab(int indent)
{
for (int i = 0; i < indent; ++i)
std::cout << ' ';
}
template< typename ExpressionNode >
struct ExpressionNodePrinter
{
ExpressionNodePrinter(int indent = 0)
: indent(indent)
{
}
void operator()(ExpressionNode const& node) const {
cout << " tag: " << node.name << endl;
for (int i=0 ; i < node.operands.size() ; i++ ) {
tab( indent ); cout << " arg "<<i<<": "; ExpressionNodePrinter(indent + 2)( node.operands[i]); cout << endl;
}
}
int indent;
};
int test() {
MockExpressionNode root;
InputGrammar< string::const_iterator , MockExpressionNode > g;
std::string litA = "litA";
std::string litB = "litB";
std::string litC = "litC";
std::string litD = "litD";
std::string litE = "litE";
std::string litF = "litF";
std::string source = litA+"( "+litB+" ,"+litC+" , "+ litD+" ( "+litE+", "+litF+" ) "+ " )";
string::const_iterator iter = source.begin();
string::const_iterator end = source.end();
bool r = qi::phrase_parse( iter , end , g , space , root );
ExpressionNodePrinter< MockExpressionNode > np;
np( root );
};
int main() {
test();
}
finally, the build error is the following:
(the full error trace is 20 times bigger than the allowed size for a stackoverflow question, so i posted the full version of it at http://codepad.org/Q74IVCUc)
/usr/bin/make -f nbproject/Makefile-linux_amd64_devel.mk SUBPROJECTS= .build-conf
make[1]: se ingresa al directorio `/home/mineq/NetBeansProjects/InputParserTests'
/usr/bin/make -f nbproject/Makefile-linux_amd64_devel.mk dist/linux_amd64_devel/GNU-Linux-x86/vpuinputparsertests
make[2]: se ingresa al directorio `/home/mineq/NetBeansProjects/InputParserTests'
mkdir -p build/linux_amd64_devel/GNU-Linux-x86
rm -f build/linux_amd64_devel/GNU-Linux-x86/tests_main.o.d
g++ `llvm-config --cxxflags` `pkg-config --cflags unittest-cpp` `pkg-config --cflags boost-1.43` `pkg-config --cflags boost-coroutines` -c -g -I../InputParser -MMD -MP -MF build/linux_amd64_devel/GNU-Linux-x86/tests_main.o.d -o build/linux_amd64_devel/GNU-Linux-x86/tests_main.o tests_main.cpp
from /home/mineq/third_party/boost_1_43_0/boost/spirit/include/phoenix_operator.hpp:11,
from ../InputParser/InputGrammar.h:14,
from tests_main.cpp:14:
/home/mineq/third_party/boost_1_43_0/boost/spirit/home/phoenix/operator/self.hpp: In instantiation of ‘const int boost::phoenix::result_of_assign<MockExpressionNode&, boost::variant<MockExpressionNode, std::basic_string<char, std::char_traits<char>, std::allocator<char> >, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_>&>::size’:
In file included from /home/mineq/third_party/boost_1_43_0/boost/spirit/home/phoenix/operator.hpp:16,
/home/mineq/third_party/boost_1_43_0/boost/spirit/home/phoenix/operator/self.hpp:27: instantiated from ‘const int boost::phoenix::result_of_assign<MockExpressionNode&, boost::variant<MockExpressionNode, std::basic_string<char, std::char_traits<char>, std::allocator<char> >, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_>&>::index’
/home/mineq/third_party/boost_1_43_0/boost/spirit/home/phoenix/operator/self.hpp:27: instantiated from ‘boost::phoenix::result_of_assign<MockExpressionNode&, boost::variant<MockExpressionNode, std::basic_string<char, std::char_traits<char>, std::allocator<char> >, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_>&>’
/home/mineq/third_party/boost_1_43_0/boost/mpl/eval_if.hpp:38: instantiated from ‘boost::mpl::eval_if<boost::mpl::or_<boost::phoenix::is_actor<MockExpressionNode&>, boost::phoenix::is_actor<boost::variant<MockExpressionNode, std::basic_string<char, std::char_traits<char>, std::allocator<char> >, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_>&>, mpl_::bool_<false>, mpl_::bool_<false>, mpl_::bool_<false> >, boost::phoenix::re_curry<boost::phoenix::assign_eval, MockExpressionNode&, boost::variant<MockExpressionNode, std::basic_string<char, std::char_traits<char>, std::allocator<char> >, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_>&, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_>, boost::phoenix::result_of_assign<MockExpressionNode&, boost::variant<MockExpressionNode, std::basic_string<char, std::char_traits<char>, std::allocator<char> >, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_>&> >’
/home/mineq/third_party/boost_1_43_0/boost/spirit/home/phoenix/operator/self.hpp:69: instantiated from ‘boost::phoenix::assign_eval::result<boost::phoenix::basic_environment<boost::fusion::vector1<boost::variant<MockExpressionNode, std::basic_string<char, std::char_traits<char>, std::allocator<char> >, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_>&>, boost::spirit::context<boost::fusion::cons<MockExpressionNode&, boost::fusion::nil>, boost::fusion::vector0<void> >, bool, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_>, boost::spirit::attribute<0>, boost::spirit::argument<0> >’
/home/mineq/third_party/boost_1_43_0/boost/spirit/home/phoenix/core/detail/composite_eval.hpp:89: instantiated from ‘boost::phoenix::detail::composite_eval<2>::result<boost::phoenix::composite<boost::phoenix::assign_eval, boost::fusion::vector<boost::spirit::attribute<0>, boost::spirit::argument<0>, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_> >, boost::phoenix::basic_environment<boost::fusion::vector1<boost::variant<MockExpressionNode, std::basic_string<char, std::char_traits<char>, std::allocator<char> >, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_>&>, boost::spirit::context<boost::fusion::cons<MockExpressionNode&, boost::fusion::nil>, boost::fusion::vector0<void> >, bool, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_> >’
/home/mineq/third_party/boost_1_43_0/boost/spirit/home/phoenix/core/composite.hpp:61: instantiated from ‘boost::phoenix::composite<boost::phoenix::assign_eval, boost::fusion::vector<boost::spirit::attribute<0>, boost::spirit::argument<0>, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_> >::result<boost::phoenix::basic_environment<boost::fusion::vector1<boost::variant<MockExpressionNode, std::basic_string<char, std::char_traits<char>, std::allocator<char> >, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_>&>, boost::spirit::context<boost::fusion::cons<MockExpressionNode&, boost::fusion::nil>, boost::fusion::vector0<void> >, bool, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_> >’
/home/mineq/third_party/boost_1_43_0/boost/spirit/home/phoenix/core/actor.hpp:56: instantiated from ‘boost::phoenix::eval_result<boost::phoenix::composite<boost::phoenix::assign_eval, boost::fusion::vector<boost::spirit::attribute<0>, boost::spirit::argument<0>, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_> >, boost::phoenix::basic_environment<boost::fusion::vector1<boost::variant<MockExpressionNode, std::basic_string<char, std::char_traits<char>, std::allocator<char> >, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_>&>, boost::spirit::context<boost::fusion::cons<MockExpressionNode&, boost::fusion::nil>, boost::fusion::vector0<void> >, bool, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_> >’
/home/mineq/third_party/boost_1_43_0/boost/spirit/home/phoenix/core/actor.hpp:65: instantiated from ‘boost::phoenix::actor<boost::phoenix::composite<boost::phoenix::assign_eval, boost::fusion::vector<boost::spirit::attribute<0>, boost::spirit::argument<0>, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_> > >::result<boost::phoenix::actor<boost::phoenix::composite<boost::phoenix::assign_eval, boost::fusion::vector<boost::spirit::attribute<0>, boost::spirit::argument<0>, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_> > >(boost::fusion::vector1<boost::variant<MockExpressionNode, std::basic_string<char, std::char_traits<char>, std::allocator<char> >, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_>&>&, boost::spirit::context<boost::fusion::cons<MockExpressionNode&, boost::fusion::nil>, boost::fusion::vector0<void> >&, bool&)>’
/home/mineq/third_party/boost_1_43_0/boost/spirit/home/support/action_dispatch.hpp:44: instantiated from ‘bool boost::spirit::traits::action_dispatch<Component>::operator()(const boost::phoenix::actor<Eval>&, Attribute&, Context&) [with Eval = boost::phoenix::composite<boost::phoenix::assign_eval, boost::fusion::vector<boost::spirit::attribute<0>, boost::spirit::argument<0>, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_> >, Attribute = boost::variant<MockExpressionNode, std::basic_string<char, std::char_traits<char>, std::allocator<char> >, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_>, Context = boost::spirit::context<boost::fusion::cons<MockExpressionNode&, boost::fusion::nil>, boost::fusion::vector0<void> >, Component = boost::spirit::qi::alternative<boost::fusion::cons<boost::spirit::qi::reference<const boost::spirit::qi::rule<__gnu_cxx::__normal_iterator<const char*, std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, MockExpressionNode(), boost::proto::exprns_::expr<boost::proto::tag::terminal, boost::proto::argsns_::term<boost::spirit::tag::char_code<boost::spirit::tag::space, boost::spirit::char_encoding::ascii> >, 0l>, boost::fusion::unused_type, boost::fusion::unused_type> >, boost::fusion::cons<boost::spirit::qi::reference<const boost::spirit::qi::rule<__gnu_cxx::__normal_iterator<const char*, std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::string(), boost::proto::exprns_::expr<boost::proto::tag::terminal, boost::proto::argsns_::term<boost::spirit::tag::char_code<boost::spirit::tag::space, boost::spirit::char_encoding::ascii> >, 0l>, boost::fusion::unused_type, boost::fusion::unused_type> >, boost::fusion::nil> > >]’
/home/mineq/third_party/boost_1_43_0/boost/spirit/home/qi/action/action.hpp:62: instantiated from ‘bool boost::spirit::qi::action<Subject, Action>::parse(Iterator&, const Iterator&, Context&, const Skipper&, Attribute&) const [with Iterator = __gnu_cxx::__normal_iterator<const char*, std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, Context = boost::spirit::context<boost::fusion::cons<MockExpressionNode&, boost::fusion::nil>, boost::fusion::vector0<void> >, Skipper = boost::spirit::qi::char_class<boost::spirit::tag::char_code<boost::spirit::tag::space, boost::spirit::char_encoding::ascii> >, Attribute = const boost::fusion::unused_type, Subject = boost::spirit::qi::alternative<boost::fusion::cons<boost::spirit::qi::reference<const boost::spirit::qi::rule<__gnu_cxx::__normal_iterator<const char*, std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, MockExpressionNode(), boost::proto::exprns_::expr<boost::proto::tag::terminal, boost::proto::argsns_::term<boost::spirit::tag::char_code<boost::spirit::tag::space, boost::spirit::char_encoding::ascii> >, 0l>, boost::fusion::unused_type, boost::fusion::unused_type> >, boost::fusion::cons<boost::spirit::qi::reference<const boost::spirit::qi::rule<__gnu_cxx::__normal_iterator<const char*, std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::string(), boost::proto::exprns_::expr<boost::proto::tag::terminal, boost::proto::argsns_::term<boost::spirit::tag::char_code<boost::spirit::tag::space, boost::spirit::char_encoding::ascii> >, 0l>, boost::fusion::unused_type, boost::fusion::unused_type> >, boost::fusion::nil> > >, Action = boost::phoenix::actor<boost::phoenix::composite<boost::phoenix::assign_eval, boost::fusion::vector<boost::spirit::attribute<0>, boost::spirit::argument<0>, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_> > >]’
/home/mineq/third_party/boost_1_43_0/boost/spirit/home/qi/nonterminal/detail/parser_binder.hpp:33: instantiated from ‘bool boost::spirit::qi::detail::parser_binder<Parser, Auto>::call(Iterator&, const Iterator&, Context&, const Skipper&, mpl_::true_) const [with Iterator = __gnu_cxx::__normal_iterator<const char*, std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, Skipper = boost::spirit::qi::char_class<boost::spirit::tag::char_code<boost::spirit::tag::space, boost::spirit::char_encoding::ascii> >, Context = boost::spirit::context<boost::fusion::cons<MockExpressionNode&, boost::fusion::nil>, boost::fusion::vector0<void> >, Parser = boost::spirit::qi::action<boost::spirit::qi::alternative<boost::fusion::cons<boost::spirit::qi::reference<const boost::spirit::qi::rule<__gnu_cxx::__normal_iterator<const char*, std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, MockExpressionNode(), boost::proto::exprns_::expr<boost::proto::tag::terminal, boost::proto::argsns_::term<boost::spirit::tag::char_code<boost::spirit::tag::space, boost::spirit::char_encoding::ascii> >, 0l>, boost::fusion::unused_type, boost::fusion::unused_type> >, boost::fusion::cons<boost::spirit::qi::reference<const boost::spirit::qi::rule<__gnu_cxx::__normal_iterator<const char*, std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::string(), boost::proto::exprns_::expr<boost::proto::tag::terminal, boost::proto::argsns_::term<boost::spirit::tag::char_code<boost::spirit::tag::space, boost::spirit::char_encoding::ascii> >, 0l>, boost::fusion::unused_type, boost::fusion::unused_type> >, boost::fusion::nil> > >, boost::phoenix::actor<boost::phoenix::composite<boost::phoenix::assign_eval, boost::fusion::vector<boost::spirit::attribute<0>, boost::spirit::argument<0>, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_> > > >, Auto = mpl_::bool_<false>]’
/home/mineq/third_party/boost_1_43_0/boost/spirit/home/qi/nonterminal/detail/parser_binder.hpp:53: instantiated from ‘bool boost::spirit::qi::detail::parser_binder<Parser, Auto>::operator()(Iterator&, const Iterator&, Context&, const Skipper&) const [with Iterator = __gnu_cxx::__normal_iterator<const char*, std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, Skipper = boost::spirit::qi::char_class<boost::spirit::tag::char_code<boost::spirit::tag::space, boost::spirit::char_encoding::ascii> >, Context = boost::spirit::context<boost::fusion::cons<MockExpressionNode&, boost::fusion::nil>, boost::fusion::vector0<void> >, Parser = boost::spirit::qi::action<boost::spirit::qi::alternative<boost::fusion::cons<boost::spirit::qi::reference<const boost::spirit::qi::rule<__gnu_cxx::__normal_iterator<const char*, std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, MockExpressionNode(), boost::proto::exprns_::expr<boost::proto::tag::terminal, boost::proto::argsns_::term<boost::spirit::tag::char_code<boost::spirit::tag::space, boost::spirit::char_encoding::ascii> >, 0l>, boost::fusion::unused_type, boost::fusion::unused_type> >, boost::fusion::cons<boost::spirit::qi::reference<const boost::spirit::qi::rule<__gnu_cxx::__normal_iterator<const char*, std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::string(), boost::proto::exprns_::expr<boost::proto::tag::terminal, boost::proto::argsns_::term<boost::spirit::tag::char_code<boost::spirit::tag::space, boost::spirit::char_encoding::ascii> >, 0l>, boost::fusion::unused_type, boost::fusion::unused_type> >, boost::fusion::nil> > >,
...
... more errors but i had to truncate to fit the 30k limit
make[2]: *** [build/linux_amd64_devel/GNU-Linux-x86/tests_main.o] Error 1
make[2]: se sale del directorio `/home/mineq/NetBeansProjects/InputParserTests'
make[1]: *** [.build-conf] Error 2
make[1]: se sale del directorio `/home/mineq/NetBeansProjects/InputParserTests'
make: *** [.build-impl] Error 2
BUILD FAILED (exit value 2, total time: 2m 13s)
Your error message tells you that you want to assign a variant<MockExpressionNode, basic_string> to a MockExpressionNode
The relevant lines are 33 and 34;
[...] error: no match for ‘operator=’ [...] boost::variant<MockExpressionNode, std::basic_string [...]
[...] candidates are: MockExpressionNode& MockExpressionNode::operator=(const MockExpressionNode&) [...]
To understand why this happens we have to look at the definitions. From the definition of a Qi rule, the signature of the returned value is defined by a template parameter. Hence
qi::rule< Iterator , ExpressionAST() , space_type > command;
means that the returned type of a command will be an ExpressionAST (i.e. a MockExpressionNode in your case). Similarly
qi::rule< Iterator , std::string() , space_type > tag;
means that tag will be of type string. Combining this with instruction = (command | tag) means that an instruction is either a string or a MockExpressionNode. This is internally stored as a variant<MockExpressionNode, string>. Finally,
qi::rule< Iterator , ExpressionAST() , space_type > instruction;
implies that the returned type of instruction is again an ExpressionAST (i.e. a MockExpressionNode). This requires the failing assignment from the variant held internally to a MockExpressionNode.
To sum up, you have to provide types in your qi::rules that somewhat "match" the types implied by your grammar in the sense that assignment is possible. Despite all the Boost.Spirit magic, C++ is still a statically typed language after all. For the issue at hand, you either have to supply a fitting operator=, or you have to assign the results of the different rules to different types that support implicit conversion. BTW, you have similar type issues for block and command at the moment. Take a careful look at the mini_xml example in the documentation: how to define types for a recursive structure and how different rules assign to different types depending on the defined grammar (especially rules xml and node).