问题描述
我有一些麻烦,使用karma生成一个结构的输出,该结构保存在boost :: shared_ptrs的向量中。我有一个小的测试用例使用ints不编译。我想我可以使用deref_iterator自定义点来处理这种情况,或者也许这种开箱即用的精神会注意到我的容器持有一个指针类型,并做额外的解引用。无论如何这里是测试用例:
I'm having some trouble using karma to generate output for a struct that is held in a vector of boost::shared_ptrs. I've got a small test case using ints that doesn't compile. I was thinking I could use the deref_iterator customization point to handle this case or that perhaps that out-of-the-box spirit would notice that my container held a pointer type and do the extra dereference. Anyway here's the test case:
#include <boost/spirit/include/karma.hpp>
#include <boost/shared_ptr.hpp>
#include <vector>
typedef boost::shared_ptr< int > ptr;
typedef std::vector< ptr > vec;
namespace boost {
namespace spirit {
namespace traits {
// specialise how iterators into containers of pointers are dereferenced
template <>
struct deref_iterator< typename container_iterator< vec const >::type >
{
typedef int type;
static
type
call( typename container_iterator< vec const >::type & it ) {
return **it;
}
};
} // namespace traits
} // namespace spirit
} // namespace boost
int
main() {
vec v;
v.push_back( ptr( new int( 1 ) ) );
v.push_back( ptr( new int( 2 ) ) );
v.push_back( ptr( new int( 3 ) ) );
using namespace boost::spirit::karma;
using boost::spirit::ascii::space;
generate_delimited(
std::ostream_iterator< char >( std::cout ),
*int_,
space,
v
);
return 0;
}
这里是编译错误:
...patience...
...patience...
...found 1986 targets...
...updating 3 targets...
gcc.compile.c++ /home/john/Dev/Bio/bin/Bio/gcc-4.6/release/src/spirit/vector-of-ptrs.o
In file included from /home/john/src/boost/boost_1_51_0/boost/spirit/home/karma/numeric/bool_policies.hpp:16:0,
from /home/john/src/boost/boost_1_51_0/boost/spirit/home/karma/numeric/bool.hpp:29,
from /home/john/src/boost/boost_1_51_0/boost/spirit/home/karma/numeric.hpp:13,
from /home/john/src/boost/boost_1_51_0/boost/spirit/home/karma.hpp:15,
from /home/john/src/boost/boost_1_51_0/boost/spirit/include/karma.hpp:16,
from src/spirit/vector-of-ptrs.cpp:1:
/home/john/src/boost/boost_1_51_0/boost/spirit/home/karma/numeric/detail/numeric_utils.hpp: In static member function ‘static boost::shared_ptr<
int> boost::spirit::traits::absolute_value<boost::shared_ptr<int>, void>::call(boost::shared_ptr<int>)’:
/home/john/src/boost/boost_1_51_0/boost/spirit/home/karma/numeric/detail/numeric_utils.hpp:149:41: instantiated from ‘boost::spirit::traits::absolute_value<boost::shared_ptr<int> >::ame boost
::spirit::traits::absolute_value<T>::type = boost::shared_ptr<int> boost::spirit::traits::get_absolute_value(boost::shared_ptr<int>)’
/home/john/src/boost/boost_1_51_0/boost/spirit/home/karma/numeric/int.hpp:213:57: instantiated from ‘static bool boost::spirit::karma::any_int_generator<
int, boost::spirit::unused_type, boost::spirit::unused_type, 10u, false
>::insert_int(boost::spirit::karma::detail::output_iterator<ostream_iterator<char>, mpl_::int_<0>, boost::spirit::unused_type> &, const boost::shared_ptr<int> &)’
/home/john/src/boost/boost_1_51_0/boost/spirit/home/karma/numeric/int.hpp:242:39: instantiated from ‘static bool boost::spirit::karma::any_int_generator<
int, boost::spirit::unused_type, boost::spirit::unused_type, 10u, false
>::generate(
boost::spirit::karma::detail::output_iterator<ostream_iterator<char>, mpl_::int_<0>, boost::spirit::unused_type> &, boost::spirit::context<
boost::fusion::cons<const vector<boost::shared_ptr<int> > &, boost::fusion::nil>, boost::spirit::locals<> > &, const boost::spirit::karma::any_space<boost::spirit::char_encoding::ascii> &
, const boost::shared_ptr<int> &)’
/home/john/src/boost/boost_1_51_0/boost/spirit/home/karma/detail/fail_function.hpp:36:62: instantiated from ‘bool boost::spirit::karma::detail::fail_function<
boost::spirit::karma::detail::output_iterator<ostream_iterator<char>, mpl_::int_<0>, boost::spirit::unused_type>, boost::spirit::context<
boost::fusion::cons<const vector<boost::shared_ptr<int> > &, boost::fusion::nil>, boost::spirit::locals<> >, boost::spirit::karma::any_space<boost::spirit::char_encoding::ascii> >
::operator()(const boost::spirit::karma::any_int_generator<int, boost::spirit::unused_type, boost::spirit::unused_type, 10u, false> &, const boost::shared_ptr<int> &) const’
/home/john/src/boost/boost_1_51_0/boost/spirit/home/karma/detail/pass_container.hpp:274:13: instantiated from ‘bool boost::spirit::karma::detail::pass_container<
boost::spirit::karma::detail::fail_function<
boost::spirit::karma::detail::output_iterator<ostream_iterator<char>, mpl_::int_<0>, boost::spirit::unused_type>, boost::spirit::context<
boost::fusion::cons<const vector<boost::shared_ptr<int> > &, boost::fusion::nil>, boost::spirit::locals<> >, boost::spirit::karma::any_space<boost::spirit::char_encoding::ascii> >,
vector<boost::shared_ptr<int> >, boost::spirit::karma::detail::indirect_iterator<vector<boost::shared_ptr<int> >::const_iterator>, mpl_::bool_<false>
>::dispatch_container(const boost::spirit::karma::any_int_generator<int, boost::spirit::unused_type, boost::spirit::unused_type, 10u, false> &, mpl_::mpl_::bool_<false>) const’
/home/john/src/boost/boost_1_51_0/boost/spirit/home/karma/detail/pass_container.hpp:321:61: [ skipping 2 instantiation contexts ]
/home/john/src/boost/boost_1_51_0/boost/spirit/home/karma/operator/kleene.hpp:53:32: instantiated from ‘bool boost::spirit::karma::base_kleene<
boost::spirit::karma::any_int_generator<int, boost::spirit::unused_type, boost::spirit::unused_type, 10u, false>, mpl_::bool_<false>, boost::spirit::karma::kleene<
boost::spirit::karma::any_int_generator<int, boost::spirit::unused_type, boost::spirit::unused_type, 10u, false> >
>::generate_subject(
boost::spirit::karma::detail::pass_container<
boost::spirit::karma::detail::fail_function<
boost::spirit::karma::detail::output_iterator<ostream_iterator<char>, mpl_::int_<0>, boost::spirit::unused_type>, boost::spirit::context<
boost::fusion::cons<const vector<boost::shared_ptr<int> > &, boost::fusion::nil>, boost::spirit::locals<> >, boost::spirit::karma::any_space<boost::spirit::char_encoding::ascii> >
, vector<boost::shared_ptr<int> >, boost::spirit::karma::detail::indirect_iterator<vector<boost::shared_ptr<int> >::const_iterator>, mpl_::bool_<false> >, const vector<
boost::shared_ptr<int> > &, mpl_::mpl_::bool_<false>) const’
/home/john/src/boost/boost_1_51_0/boost/spirit/home/karma/operator/kleene.hpp:126:17: instantiated from ‘bool boost::spirit::karma::base_kleene<
boost::spirit::karma::any_int_generator<int, boost::spirit::unused_type, boost::spirit::unused_type, 10u, false>, mpl_::bool_<false>, boost::spirit::karma::kleene<
boost::spirit::karma::any_int_generator<int, boost::spirit::unused_type, boost::spirit::unused_type, 10u, false> >
>::generate(
boost::spirit::karma::detail::output_iterator<ostream_iterator<char>, mpl_::int_<0>, boost::spirit::unused_type> &, boost::spirit::context<
boost::fusion::cons<const vector<boost::shared_ptr<int> > &, boost::fusion::nil>, boost::spirit::locals<> > &, const boost::spirit::karma::any_space<boost::spirit::char_encoding::ascii> &
, const vector<boost::shared_ptr<int> > &) const’
/home/john/src/boost/boost_1_51_0/boost/spirit/home/karma/generate.hpp:161:53: instantiated from ‘bool boost::spirit::karma::generate_delimited(
boost::spirit::karma::detail::output_iterator<ostream_iterator<char>, mpl_::int_<0> > &, const boost::proto::exprns_::expr<
boost::proto::tagns_::tag::dereference, boost::proto::argsns_::list1<const boost::spirit::terminal<boost::spirit::tag::int_> &>, 1l> &, const 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> >, 0l> &, boost::spirit
::karma::delimit_flag::enum_type, const vector<boost::shared_ptr<int> > &)’
/home/john/src/boost/boost_1_51_0/boost/spirit/home/karma/generate.hpp:185:82: instantiated from ‘bool boost::spirit::karma::generate_delimited(
ostream_iterator<char> &, const boost::proto::exprns_::expr<boost::proto::tagns_::tag::dereference, boost::proto::argsns_::list1<const boost::spirit::terminal<boost::spirit::tag::int_> &>,
1l> &, const 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> >, 0l> &, boost::spirit
::karma::delimit_flag::enum_type, const vector<boost::shared_ptr<int> > &)’
/home/john/src/boost/boost_1_51_0/boost/spirit/home/karma/generate.hpp:227:48: instantiated from ‘bool boost::spirit::karma::generate_delimited(
const ostream_iterator<char> &, const boost::proto::exprns_::expr<
boost::proto::tagns_::tag::dereference, boost::proto::argsns_::list1<const boost::spirit::terminal<boost::spirit::tag::int_> &>, 1l> &, const 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> >, 0l> &, const vector<
boost::shared_ptr<int> > &)’
src/spirit/vector-of-ptrs.cpp:46:2: instantiated from here
/home/john/src/boost/boost_1_51_0/boost/spirit/home/karma/numeric/detail/numeric_utils.hpp:60:26: error: No match for ‘fabs(boost::shared_ptr<int> &)’
STL Decryptor reminder:
Use the /cand:L option to see all suppressed template candidates
"/home/john/src/stlfilt/gfilt" -ftemplate-depth-128 -Wno-deprecated -Wno-unused -Wno-error -O3 -finline-functions -Wno-inline -Wall -fPIC -Wno-deprecated -Wno-unused -DBOOST_FILESYSTEM_VERSION=3 -DNDEBUG -DWITH_NONAMESPACES -DXML_LIBRARY -I"../Bio" -I"../Hmm" -I"/home/john/src/boost/boost_1_51_0" -c -o "/home/john/Dev/Bio/bin/Bio/gcc-4.6/release/src/spirit/vector-of-ptrs.o" "src/spirit/vector-of-ptrs.cpp"
...failed gcc.compile.c++ /home/john/Dev/Bio/bin/Bio/gcc-4.6/release/src/spirit/vector-of-ptrs.o...
...removing /home/john/Dev/Bio/bin/Bio/gcc-4.6/release/src/spirit/vector-of-ptrs.o
...skipped <p/home/john/Dev/Bio/bin/Bio/gcc-4.6/release>spirit-vector-of-ptrs for lack of <p/home/john/Dev/Bio/bin/Bio/gcc-4.6/release>src/spirit/vector-of-ptrs.o...
...failed updating 1 target...
...skipped 1 target...
推荐答案
专业化没有被实例化,期望的是:迭代器在 evalation 期间变成了包裹( karma :: detail :: indirect_iterator
)生成器表达式。
A bit of experimentation lead me to the reason why the specialization wasn't instantiatied, where expected: the iterator has become wrapped (with karma::detail::indirect_iterator
) somewhere during the evalation of the generator expression.
以下是适用于我的修复程序:
Here is the fix that works for me:
namespace boost {
namespace spirit {
namespace traits {
// specialise how iterators into containers of pointers are dereferenced
template <>
struct deref_iterator< karma::detail::indirect_iterator<vec::const_iterator> >
{
typedef karma::detail::indirect_iterator<vec::const_iterator> It;
typedef int type;
static type call( It const & it ) {
return **it;
}
};
} // namespace traits
} // namespace spirit
} // namespace boost
这篇关于使用karma生成指针向量的输出的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!