strange template namespace problem - c++

I've got a strange problem with templates and namespaces...
I have the following code which compiles fine..
using namespace boost::multi_index;
template < typename OT, typename KT, KT (OT::* KM)() const, typename KC, typename CMP >
class OrderBook
{
public:
OrderBook() {}
~OrderBook() {}
typedef multi_index_container<
OT,
indexed_by<
ordered_unique<
const_mem_fun< OT, KT, KM >,
KC
>,
ordered_unique<
identity< OT >,
CMP
>
>
> Container;
typedef typename Container::template nth_index< 0 >::type index_0;
typedef typename Container::template nth_index< 1 >::type index_1;
typedef typename index_0::const_iterator const_iterator_0;
typedef typename index_1::const_iterator const_iterator_1;
const_iterator_0 begin0() const { return _container.get<0>().begin(); }
const_iterator_0 end0() const { return _container.get<0>().end(); }
public:
Container _container;
};
However, due to a namespace collision when I insert this code into another project I have to have... (Notice how I've had to remove the using namespace boost::multi_index and manually specify it where needed
template < typename OT, typename KT, KT (OT::* KM)() const, typename KC, typename CMP >
class OrderBook
{
public:
OrderBook() {}
~OrderBook() {}
typedef boost::multi_index::multi_index_container<
OT,
boost::multi_index::indexed_by<
boost::multi_index::ordered_unique<
boost::multi_index::const_mem_fun< OT, KT, KM >,
KC
>,
boost::multi_index::ordered_unique<
boost::multi_index::identity< OT >,
CMP
>
>
> Container;
typedef typename Container::template nth_index< 0 >::type index_0;
typedef typename Container::template nth_index< 1 >::type index_1;
typedef typename index_0::const_iterator const_iterator_0;
typedef typename index_1::const_iterator const_iterator_1;
const_iterator_0 begin0() const { return _container.get<0>().begin(); }
const_iterator_0 end0() const { return _container.get<0>().end(); }
public:
Container _container;
};
Which gives me the following error from g++.
In member function 'typename boost::multi_index::multi_index_container<OT, boost::multi_index::indexed_by<boost::multi_index::ordered_unique<boost::multi_index::const_mem_fun<OT, KT, KM>, KC, mpl_::na>, boost::multi_index::ordered_unique<boost::multi_index::identity<Value>, CMP, mpl_::na>, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na>, std::allocator<_CharT> >::nth_index<0>::type::const_iterator OrderBook<OT, KT, KM, KC, CMP>::begin0() const':
error: expected primary-expression before ')' token
In member function 'typename boost::multi_index::multi_index_container<OT, boost::multi_index::indexed_by<boost::multi_index::ordered_unique<boost::multi_index::const_mem_fun<OT, KT, KM>, KC, mpl_::na>, boost::multi_index::ordered_unique<boost::multi_index::identity<Value>, CMP, mpl_::na>, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na>, std::allocator<_CharT> >::nth_index<0>::type::const_iterator OrderBook<OT, KT, KM, KC, CMP>::end0() const':
error: expected primary-expression before ')' token
Sorry for the long error messages, I did consider cleaning them up but I thought I'd better leave them intact in case I removed something crucial.
I tried this...
typedef typename Container::template boost::multi_index::nth_index< 0 >::type index_0;
typedef typename Container::template boost::multi_index::nth_index< 1 >::type index_1;
and it just made g++ even madder :(
Any ideas?

Prefix get<0>() with template:
const_iterator_0 begin0() const { return _container.template get<0>().begin(); }
const_iterator_0 end0 () const { return _container.template get<0>().end(); }
Similar to typename for dependent types, dependent templates have to be prefixed by template:
struct X {
template<class T> void f();
};
template<class T>
void test() {
T::f<int>(); // ill-formed
T::template f<int>(); // ok
}
// ...
test<X>();
And for the curious, that is ยง14.2/4:
When the name of a member template
specialization appears after . or ->
in a postfix-expression, or after
nested-name-specifier in a
qualified-id, and the
postfix-expression or qualified-id
explicitly depends on a
template-parameter (14.6.2), the
member template name must be prefixed
by the keyword template. Otherwise the
name is assumed to name a
non-template.

Maybe I can guess that some of these functions are not in the boost::multi_index namespace: indexed_b, ordered_unique, const_mem_fun, or identity

Related

making shared_ptr's from Boost.Spirit.Qi

I would like to use a Spirit Qi grammar to parse text into shared pointers to strings. Actually, I would like to parse multivariate polynomials into a system of them, with various kinds of previously-encountered symbols appearing in the polynomials, but for now, let's parse from text into std::shared_ptr<std::string>.
I have been floundering for a long time now, and have distilled this small test grammar in a header file:
#define BOOST_SPIRIT_USE_PHOENIX_V3 1
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix.hpp>
#include <boost/spirit/include/phoenix_operator.hpp>
#include <boost/bind.hpp>
namespace qi = boost::spirit::qi;
namespace ascii = boost::spirit::ascii;
template<typename Iterator>
struct SharedPtrParser : qi::grammar<Iterator, std::shared_ptr<std::string>(), boost::spirit::ascii::space_type>
{
SharedPtrParser() : SharedPtrParser(startrule)
{
startrule = qi::eps[ qi::_val = std::make_shared<std::string>()];
}
qi::rule<Iterator,std::shared_ptr<std::string>()> startrule;
};
and this usage of it in main:
#include "shared_ptr_test.h"
int main()
{
SharedPtrParser<std::string::const_iterator> C;
std::string text = "thisissometext";
auto iter = text.begin();
auto end = text.end();
std::shared_ptr<std::string> S;
bool s = phrase_parse(iter, end, C,boost::spirit::ascii::space, S);
return 0;
}
I am aware that my grammar doesn't do squat. I just want to make shared pointers from Qi right now! To this end, I've found a number of hints regarding using smart pointers in conjunction with Qi, but no grammars which are factories for them. I feel like I've been close, especially having found this post by sehe from Spirit General discussion forum. However, I just haven't been able to put it together yet.
Attempts at compilation produce two errors as written ATM.
one:
./shared_ptr_test.h:16:22: error: no matching constructor for initialization of 'SharedPtrParser<std::__1::__wrap_iter<const char *> >'
SharedPtrParser() : SharedPtrParser(startrule)
^ ~~~~~~~~~
shared_ptr_test.cpp:8:47: note: in instantiation of member function 'SharedPtrParser<std::__1::__wrap_iter<const char *> >::SharedPtrParser' requested here
SharedPtrParser<std::string::const_iterator> C;
^
./shared_ptr_test.h:14:8: note: candidate constructor (the implicit copy constructor) not viable: no known conversion from 'qi::rule<__wrap_iter<const char *>,
std::shared_ptr<std::string> ()>' to 'const SharedPtrParser<std::__1::__wrap_iter<const char *> >' for 1st argument
struct SharedPtrParser : qi::grammar<Iterator, std::shared_ptr<std::string>(), boost::spirit::ascii::space_type>
^
./shared_ptr_test.h:16:2: note: candidate constructor not viable: requires 0 arguments, but 1 was provided
SharedPtrParser() : SharedPtrParser(startrule)
^
two:
In file included from shared_ptr_test.cpp:1:
In file included from ./shared_ptr_test.h:4:
In file included from /usr/local/include/boost/spirit/include/qi.hpp:16:
In file included from /usr/local/include/boost/spirit/home/qi.hpp:21:
In file included from /usr/local/include/boost/spirit/home/qi/nonterminal.hpp:14:
In file included from /usr/local/include/boost/spirit/home/qi/nonterminal/rule.hpp:35:
/usr/local/include/boost/spirit/home/qi/reference.hpp:43:30: error: no matching member function for call to 'parse'
return ref.get().parse(first, last, context, skipper, attr_);
~~~~~~~~~~^~~~~
/usr/local/include/boost/spirit/home/qi/parse.hpp:164:40: note: in instantiation of function template specialization 'boost::spirit::qi::reference<const
boost::spirit::qi::rule<std::__1::__wrap_iter<const char *>, std::__1::shared_ptr<std::__1::basic_string<char> > (),
boost::proto::exprns_::expr<boost::proto::tagns_::tag::terminal, boost::proto::argsns_::term<boost::spirit::tag::char_code<boost::spirit::tag::space,
boost::spirit::char_encoding::ascii> >, 0>, boost::spirit::unused_type, boost::spirit::unused_type> >::parse<std::__1::__wrap_iter<char *>,
boost::spirit::context<boost::fusion::cons<std::__1::shared_ptr<std::__1::basic_string<char> > &, boost::fusion::nil_>, boost::spirit::locals<mpl_::na, mpl_::na, mpl_::na,
mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na> >, boost::spirit::qi::char_class<boost::spirit::tag::char_code<boost::spirit::tag::space,
boost::spirit::char_encoding::ascii> >, std::__1::shared_ptr<std::__1::basic_string<char> > >' requested here
if (!compile<qi::domain>(expr).parse(
^
/usr/local/include/boost/spirit/home/qi/parse.hpp:197:20: note: in instantiation of function template specialization 'boost::spirit::qi::phrase_parse<std::__1::__wrap_iter<char *>,
SharedPtrParser<std::__1::__wrap_iter<const char *> >, boost::proto::exprns_::expr<boost::proto::tagns_::tag::terminal,
boost::proto::argsns_::term<boost::spirit::tag::char_code<boost::spirit::tag::space, boost::spirit::char_encoding::ascii> >, 0>, std::__1::shared_ptr<std::__1::basic_string<char>
> >' requested here
return qi::phrase_parse(first, last, expr, skipper, skip_flag::postskip, attr);
^
shared_ptr_test.cpp:18:11: note: in instantiation of function template specialization 'boost::spirit::qi::phrase_parse<std::__1::__wrap_iter<char *>,
SharedPtrParser<std::__1::__wrap_iter<const char *> >, boost::proto::exprns_::expr<boost::proto::tagns_::tag::terminal,
boost::proto::argsns_::term<boost::spirit::tag::char_code<boost::spirit::tag::space, boost::spirit::char_encoding::ascii> >, 0>, std::__1::shared_ptr<std::__1::basic_string<char>
> >' requested here
bool s = phrase_parse(iter, end, C,boost::spirit::ascii::space, S);
^
/usr/local/include/boost/spirit/home/qi/nonterminal/rule.hpp:274:14: note: candidate function [with Context =
boost::spirit::context<boost::fusion::cons<std::__1::shared_ptr<std::__1::basic_string<char> > &, boost::fusion::nil_>, boost::spirit::locals<mpl_::na, mpl_::na, mpl_::na,
mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na> >, Skipper = boost::spirit::qi::char_class<boost::spirit::tag::char_code<boost::spirit::tag::space,
boost::spirit::char_encoding::ascii> >, Attribute = std::__1::shared_ptr<std::__1::basic_string<char> >] not viable: no known conversion from 'std::__1::__wrap_iter<char *>' to
'std::__1::__wrap_iter<const char *> &' for 1st argument
bool parse(Iterator& first, Iterator const& last
^
/usr/local/include/boost/spirit/home/qi/nonterminal/rule.hpp:320:14: note: candidate function template not viable: requires 6 arguments, but 5 were provided
bool parse(Iterator& first, Iterator const& last
A little help?
My problem here was trivial and noobish. I failed to specify for the constructor, ::base_type. That is, the line for SharedPtrParser() : SharedPtrParser(startrule) should have been SharedPtrParser() : SharedPtrParser::base_type(startrule).

forward-declaring boost.type_erasure reference type

I am using boost.type_erasure in my codebase. So far the experience,
given what it enables, has been very good.
I want to be able to forward-declare a " type-erased reference type" for my API. This leaves outside using and typedef because they do not allow
forward declarations.
For a value type everything is fine:
class any_game_state : public
boost::type_erasure::any<
boost::mpl::vector<has_enter<void ()>,
has_update<bool (std::chrono::milliseconds)>,
has_exit<int ()>,
has_get_resolution<std::pair<int, int> (),
const
boost::type_erasure::_self>,
has_get_position<std::pair<int, int> (),
const
boost::type_erasure::_self>,
has_get_scene_root<boost::any (), const
boost::type_erasure::_self>,
boost::type_erasure::copy_constructible<>,
boost::type_erasure::relaxed>> {
using base = boost::type_erasure::any<...identical_contents>;
using base::base;
};
But when I try to do the same for its corresponding reference, it is not working:
class any_game_state_ref : public
boost::type_erasure::any<
boost::mpl::vector<has_enter<void ()>,
has_update<bool (std::chrono::milliseconds)>,
has_exit<int ()>,
has_get_resolution<std::pair<int, int> (),
const
boost::type_erasure::_self>,
has_get_position<std::pair<int, int> (),
const
boost::type_erasure::_self>,
has_get_scene_root<boost::any (), const
boost::type_erasure::_self>,
boost::type_erasure::copy_constructible<>,
boost::type_erasure::relaxed>,
boost::type_erasure::_self&> {
using base = boost::type_erasure::any<...identical_contents>;
using base::base;
};
If I use using for the "reference type" everything works fine, but I lose the ability to forward-declare the reference type.
The error I get is the following:
In file included from src/barvie/controller/game_action_state.cpp:3:
In file included from /usr/local/include/boost/type_erasure/any_cast.hpp:24:
/usr/local/include/boost/type_erasure/any.hpp:1290:12: error: no type named 'type' in 'boost::disable_if, has_update >), boost::type_erasure::_self>, has_exit, has_get_resolution (), const boost::type_erasure::_self>, has_get_position (), const boost::type_erasure::_self>, has_get_scene_root, boost::type_erasure::copy_constructible, boost::type_erasure::relaxed, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na>, boost::mpl::vector, has_update >), boost::type_erasure::_self>, has_exit, has_get_resolution (), const boost::type_erasure::_self>, has_get_position (), const boost::type_erasure::_self>, has_get_scene_root, boost::type_erasure::copy_constructible, boost::type_erasure::relaxed, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na> >, boost::is_const, mpl_::bool_, mpl_::bool_, mpl_::bool_ >, void>'
::type* = 0
~~~^~~~
../libbarvie/src/barvie/controller/any_game_state.hpp:95:17: note: in instantiation of member function 'boost::type_erasure::any, has_update >), boost::type_erasure::_self>, has_exit, has_get_resolution (), const boost::type_erasure::_self>, has_get_position (), const boost::type_erasure::_self>, has_get_scene_root, boost::type_erasure::copy_constructible, boost::type_erasure::relaxed, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na>, boost::type_erasure::_self &>::any' requested here
using base::base;
^
src/barvie/controller/game_action_state.cpp:291:18: note: while substituting deduced template arguments into function template 'any_game_state_ref' [with Concept2 = boost::mpl::vector, has_update >), boost::type_erasure::_self>, has_exit, has_get_resolution (), const boost::type_erasure::_self>, has_get_position (), const boost::type_erasure::_self>, has_get_scene_root, boost::type_erasure::copy_constructible, boost::type_erasure::relaxed, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na>, Tag2 = boost::type_erasure::_self]
(this,
^
In file included from src/barvie/controller/game_action_state.cpp:3:
In file included from /usr/local/include/boost/type_erasure/any_cast.hpp:24:
/usr/local/include/boost/type_erasure/any.hpp:1323:12: error: no type named 'type' in 'boost::disable_if, has_update >), boost::type_erasure::_self>, has_exit, has_get_resolution (), const boost::type_erasure::_self>, has_get_position (), const boost::type_erasure::_self>, has_get_scene_root, boost::type_erasure::copy_constructible, boost::type_erasure::relaxed, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na>, boost::mpl::vector, has_update >), boost::type_erasure::_self>, has_exit, has_get_resolution (), const boost::type_erasure::_self>, has_get_position (), const boost::type_erasure::_self>, has_get_scene_root, boost::type_erasure::copy_constructible, boost::type_erasure::relaxed, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na> >, boost::is_const, mpl_::bool_, mpl_::bool_, mpl_::bool_ >, void>'
::type = 0
~~~^~~~
../libbarvie/src/barvie/controller/any_game_state.hpp:95:17: note: in instantiation of member function 'boost::type_erasure::any, has_update >), boost::type_erasure::_self>, has_exit, has_get_resolution (), const boost::type_erasure::_self>, has_get_position (), const boost::type_erasure::_self>, has_get_scene_root, boost::type_erasure::copy_constructible, boost::type_erasure::relaxed, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na>, boost::type_erasure::_self &>::any' requested here
using base::base;
^
src/barvie/controller/game_action_state.cpp:291:18: note: while substituting deduced template arguments into function template 'any_game_state_ref' [with Concept2 = boost::mpl::vector, has_update >), boost::type_erasure::_self>, has_exit, has_get_resolution (), const boost::type_erasure::_self>, has_get_position (), const boost::type_erasure::_self>, has_get_scene_root, boost::type_erasure::copy_constructible, boost::type_erasure::relaxed, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na>, Tag2 = boost::type_erasure::_self &]
(*this,
I found a solution. The solution is to give up on inherited constructors for the reference type, instead of the inherited constructor I used an equivalent by-hand inherited constructor. It seems that maybe something about templates mixed with inherited constructors did not play well:
template <class...Args>
any_game_state_ref(Args &&... args) : base(std::forward<Args>(args)...)
{}
This did the trick and now I can forward declare type erased references also.

Extending boost variant with an MPL list

I'm trying to provide a program a way to add new objects to a variant in a library but I'm encountering some cryptic errors.
#include <boost/mpl/copy.hpp>
#include <boost/mpl/joint_view.hpp>
#include <boost/mpl/list.hpp>
#include <boost/variant/variant.hpp>
struct InternalType1 {};
struct InternalType2 {};
template <typename LocalTypes>
struct Foo
{
typedef boost::mpl::list<
InternalType1,
InternalType2
> Types;
typename boost::make_variant_over<
typename boost::mpl::joint_view<
Types,
LocalTypes
>::type
>::type container_;
// typename boost::make_variant_over<
// typename boost::mpl::copy<
// LocalTypes,
// boost::mpl::back_inserter<Types>
// >::type
// >::type container_;
};
struct LocalType1 {};
struct LocalType2 {};
int main()
{
typedef boost::mpl::list<
LocalType1,
LocalType2
> Types;
Foo<Types> foo;
}
By using a mpl::joint_view (which I assume if the most efficient way of achieving this), I get the following error:
/usr/local/include/boost/mpl/clear.hpp:29:7: error: implicit instantiation of undefined template
By uncommenting the other attempt, using mpl::copy, and replacing it with the original, then the error changes:
/usr/local/include/boost/mpl/aux_/push_back_impl.hpp:40:9: error: no matching function for call to 'assertion_failed'
Which, interestingly, has the following comment:
// should be instantiated only in the context of 'has_push_back_impl';
// if you've got an assert here, you are requesting a 'push_back'
// specialization that doesn't exist.
Neither of these errors make any sense to me as, w/r/t the first, I don't see which templates are not complete and for the second, which push_back specialization I'm not using?
The problem is that boost::mpl::clear<> is not implemented for a joint_view... hence the huge compiler dump terminating with:
/usr/local/include/boost/mpl/clear.hpp:29:7: error: implicit instantiation of undefined template 'boost::mpl::clear_impl<boost::mpl::aux::joint_view_tag>::apply<boost::mpl::joint_view<boost::mpl::list<InternalType1, InternalType2, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na>, boost::mpl::list<LocalType1, LocalType2, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na> > >'
(I don't know how to format that properly)
This could be just an oversight in the library, or it may just not be clear which empty Sequence type should be returned in this case. If you want to use a joint_view, you'll have to provide a specialization of clear_impl somewhere:
namespace boost { namespace mpl {
template <>
struct clear_impl<aux::joint_view_tag>
{
template <typename JV>
struct apply {
typedef list<> type; // since you're using list I figured
// I would too.
};
};
} }
With that, your code compiles for me on both gcc and clang.
Alternatively, if adding stuff into namespace boost::mpl strikes you as a little shady but you still want to stick with lists, you can just use insert_range:
typename boost::make_variant_over<
typename boost::mpl::insert_range<
Types,
typename boost::mpl::end<Types>::type,
LocalTypes
>::type
>::type container_;

How to declare a boost recursive variant in mpl::list?

How can I make this recursive variant work? I'd like to have a container of variant, or container of container of variant.
template <class T>
class A
{
// ...
T t_;
};
template <class T>
class AVariant
{
typedef typename boost::make_variant_over<T>::type Type;
Type t;
// ...
};
template <class Container>
class Composite
{
typedef typename Container::value_type T;
Container container_of_any_;
// ....
};
In main.cpp:
typedef AVariant<boost::mpl::list<
A<int>,
A<long>,
boost::recursive_wrapper<Composite<std::vector<Any> > > // Compile error: 'Any' is not declared in this scope
> > Any;
I understand that Compoiste > is not right, but not sure how?
Edit:
I've changed the following:
template <class T>
class AVariant
{
typedef typename boost::make_recursive_variant_over<T>::type Type;
Type t_;
// ...
template <class Archive>
class SerializeVisitor : public boost::static_visitor<>
{
SerializeVisitor( Archive& ar ) : ar_(ar) {}
template <typename U>
void operator()( const U& t ) const
{
ar_ & BOOST_SERIALIZATION_NVP( t );
}
};
friend class boost::serialization::access;
template<class Archive>
void serialize( Archive& ar, const unsigned int version )
{
boost::apply_visitor( SerializeVisitor<Archive>( ar ), t_ );
}
};
Then instantiate using:
typedef AVariant<boost::mpl::list<
A<double>,
A<int>,
std::vector<boost::recursive_variant_> // to make the recursion slightly simplier
> > Any;
And my AVariant has a visitor to serialize as above. It still gives compile error when serialization is invoked in main(). It seems to look for serialize() function for the class std::vector in the error:
const class std::vector<boost::variant<boost::detail::variant::recursive_flag<boost::detail::variant::over_sequence<boost::mpl::vector<A<double>, A<long int>, A, std::vector<boost::recursive_variant_, std::allocator<boost::recursive_variant_> >, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na> > >, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_>, std::allocator<boost::variant<boost::detail::variant::recursive_flag<boost::detail::variant::over_sequence<boost::mpl::vector<A<double>, A<long int>, A, std::vector<boost::recursive_variant_, std::allocator<boost::recursive_variant_> >, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na> > >, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, 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 'serialize'
You need to use boost::make_recursive_variant instead of boost::recursive_wrapper with boost::recursive_variant_ in it.So you should try this:
typedef AVariant<boost::mpl::list<
A<int>,
A<long>,
boost::make_recursive_variant<Composite<std::vector<boost::recursive_variant_> >
>::type > > Any;
This can help you.
You should refer here: http://www.boost.org/doc/libs/1_54_0/doc/html/variant/tutorial.html#variant.tutorial.recursive.recursive-variant
and here http://www.boost.org/doc/libs/1_54_0/boost/variant/recursive_variant.hpp for more information about recursive variants.
If you want to serialize variant you should better use boost::variant visitation mechanism to write out the actual type contained in the variant:
variant_serializer ser;
boost::apply_visitor( ser, your_variant);

gdb.lookup_type returns invalid type with boost::multi_index_container

I'm using gdb-7.5, on RHEL 6, compiled with gcc-4.7.2. I'm trying to
write a pretty printer for boost::multi_index and ran into problems
with gdb.lookup_type.
Below given code has the following declaration.
TestSet ts;
Now, at the gdb command prompt, I'm performing the following
operations (in python)
gdb >> python
set_value = gdb.parse_and_eval('ts')
set_type = set_value.type.strip_typedefs()
t1 = set_type.template_argument(0) # Test
t2 = set_type.template_argument(1) # boost::mult_index::indexed_by ....
t3 = set_type.template_argument(2) # std::allocator<Test>
node_type = gdb.lookup_type('boost::multi_index::detail::multi_index_node_type < %s, %s, %s >::type' % (t1, t2, t3))
base = gdb.lookup_type ('boost::multi_index::detail::multi_index_base_type < %s, %s, %s >::type' % (t1, t2, t3))
allocator = gdb.lookup_type('boost::detail::allocator::rebind_to<%s, %s>::type' % (t3, node_type))
end
I'm getting the node_type correctly. But gdb is unable to get types
for 'base' and 'allocator'.
The error for base
Traceback (most recent call last):
File "<string>", line 1, in <module>
gdb.error: No type named boost::detail::multi_index_base_type < Test,
boost::multi_index::indexed_by<boost::multi_index::ordered_unique<boost::multi_index::member<Test,
std::basic_string<char, std::char_traits<char>, std::allocator<char>
>, &Test::s>, mpl_::na, mpl_::na>
, boost::multi_index::ordered_unique<boost::multi_index::tag<int,
mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na,
mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na,
mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na>, boost::multi_i
ndex::member<Test, int, &Test::i>, mpl_::na>,
boost::multi_index::ordered_unique<boost::multi_index::member<Test,
float, &Test::f>, mpl_::na, mpl_::na>, mpl_::na, mpl_::na, mpl_::na,
mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na,
mpl_::na, mpl_::na
, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na>,
std::allocator<Test> >::type.
Error while executing Python code.
and a similar error for 'allocator'.
As boost::multi_index_container is derived from
boost::detail::multi_index_base_type, I'm expecting gdb to return a
valid type for the same.
Am I missing something here. ?
I've posted the same question in gdb mailing list but there was no answer.
The code:
#include <string>
using namespace std;
#include <boost/multi_index_container.hpp>
#include <boost/multi_index/member.hpp>
#include <boost/multi_index/key_extractors.hpp>
#include <boost/multi_index/ordered_index.hpp>
#include <boost/multi_index/hashed_index.hpp>
#include <boost/multi_index/sequenced_index.hpp>
#include <boost/multi_index/random_access_index.hpp>
using namespace boost::multi_index;
using namespace boost;
struct Test
{
Test (const string& ps, int pi, float pf)
: s(ps), i(pi), f(pf)
{
}
string s;
int i;
float f;
};
typedef multi_index_container <
Test,
indexed_by <
ordered_unique < member <Test, string, &Test::s> >,
ordered_unique < tag<int>, member <Test, int, &Test::i> >,
ordered_unique < member <Test, float, &Test::f> >
>
> TestSet;
int main(void)
{
TestSet ts;
ts.insert(Test("ABCDEF", 10, 1.0f));
ts.insert(Test("Some String", 5, 2.0f));
ts.insert(Test("PQRXYZ", 7, 0.3f));
return 0;
}
Surya
I would start by trying to find out whether this type actually does exist. One way would be to dig through the "readelf -wi" output. This dumps the DWARF information for your program. However, it is likely to be very large, and so it may take a while.
If it exists in the DWARF then I would debug gdb to see what is going wrong.
If it isn't in the DWARF then it may be a compiler error, or just wrong compilation arguments.