I have a series of vectors which I am adding into a DataFrame object to return to R.
The problem comes when I try and add a vector with long long elements.
// [[Rcpp::export]]
DataFrame test()
{
std::vector<long long> x;
return DataFrame::create(Named("x") = x);
}
The error returned is
g++ -m64 -I"C:/R/R-30~1.1/include" -DNDEBUG -I"C:/R/R-3.0.1/library/Rcpp/include" -I"d:/RCompile/CRANpkg/extralibs64/local/include" -O2 -Wall -mtune=core2 -c quotes.cpp -o quotes.o In file included from C:/R/R-3.0.1/library/Rcpp/include/RcppCommon.h:117:0, from C:/R/R-3.0.1/library/Rcpp/include/Rcpp.h:27, from quotes.cpp:1: C:/R/R-3.0.1/library/Rcpp/include/Rcpp/internal/wrap.h: In function 'SEXPREC* Rcpp::internal::wrap_dispatch_unknown_iterable(const T&, Rcpp::traits::false_type) [with T = long long int, SEXP = SEXPREC*, Rcpp::traits::false_type = Rcpp::traits::integral_constant]': C:/R/R-3.0.1/library/Rcpp/include/Rcpp/internal/wrap.h:691:98: instantiated from 'SEXPREC* Rcpp::internal::wrap_dispatch_unknown(const T&, Rcpp::traits::false_type) [with T = long long int, SEXP = SEXPREC*, Rcpp::traits::false_type = Rcpp::traits::integral_constant]' C:/R/R-3.0.1/library/Rcpp/include/Rcpp/internal/wrap.h:723:96: instantiated from 'SEXPREC* Rcpp::internal::wrap_dispatch_eigen(const T&, Rcpp::traits::false_type) [with T = long long int, SEXP = SEXPREC*, Rcpp::traits::false_type = Rcpp::traits::integral_constant]' C:/R/R-3.0.1/library/Rcpp/include/Rcpp/internal/wrap.h:740:80: instantiated from 'SEXPREC* Rcpp::internal::wrap_dispatch_unknown_importable(const T&, Rcpp::traits::false_type) [with T = long long int, SEXP = SEXPREC*, Rcpp::traits::false_type = Rcpp::traits::integral_constant]' C:/R/R-3.0.1/library/Rcpp/include/Rcpp/internal/wrap.h:760:99: instantiated from 'SEXPREC* Rcpp::internal::wrap_dispatch(const T&, Rcpp::traits::wrap_type_unknown_tag) [with T = long long int, SEXP = SEXPREC*]' C:/R/R-3.0.1/library/Rcpp/include/Rcpp/internal/wrap.h:863:104: instantiated from 'SEXPREC* Rcpp::wrap(const T&) [with T = long long int, SEXP = SEXPREC*]' C:/R/R-3.0.1/library/Rcpp/include/Rcpp/internal/wrap.h:193:3: [ skipping 14 instantiation contexts ] C:/R/R-3.0.1/library/Rcpp/include/Rcpp/vector/Vector.h:395:9: instantiated from 'static void Rcpp::Vector::replace_element__dispatch(Rcpp::traits::true_type, Rcpp::Vector::iterator, SEXP, int, const U&) [with U = Rcpp::traits::named_object >, int RTYPE = 19, Rcpp::traits::true_type = Rcpp::traits::integral_constant, Rcpp::Vector::iterator = Rcpp::internal::Proxy_Iterator >, SEXP = SEXPREC*]' C:/R/R-3.0.1/library/Rcpp/include/Rcpp/vector/Vector.h:384:9: instantiated from 'static void Rcpp::Vector::replace_element(Rcpp::Vector::iterator, SEXP, int, const U&) [with U = Rcpp::traits::named_object >, int RTYPE = 19, Rcpp::Vector::iterator = Rcpp::internal::Proxy_Iterator >, SEXP = SEXPREC*]' C:/R/R-3.0.1/library/Rcpp/include/Rcpp/generated/Vector_create.h:318:2: instantiated from 'static Rcpp::Vector Rcpp::Vector::create_dispatch(Rcpp::traits::true_type, const T1&, const T2&, const T3&, const T4&, const T5&, const T6&) [with T1 = Rcpp::traits::named_object >, T2 = Rcpp::traits::named_object >, T3 = Rcpp::traits::named_object >, T4 = Rcpp::traits::named_object >, T5 = Rcpp::traits::named_object >, T6 = Rcpp::traits::named_object >, int RTYPE = 19, Rcpp::Vector = Rcpp::Vector<19>, Rcpp::traits::true_type = Rcpp::traits::integral_constant]' C:/R/R-3.0.1/library/Rcpp/include/Rcpp/generated/Vector__create.h:288:37: instantiated from 'static Rcpp::Vector Rcpp::Vector::create(const T1&, const T2&, const T3&, const T4&, const T5&, const T6&) [with T1 = Rcpp::traits::named_object >, T2 = Rcpp::traits::named_object >, T3 = Rcpp::traits::named_object >, T4 = Rcpp::traits::named_object >, T5 = Rcpp::traits::named_object >, T6 = Rcpp::traits::named_object >, int RTYPE = 19, Rcpp::Vector = Rcpp::Vector<19>]' C:/R/R-3.0.1/library/Rcpp/include/Rcpp/generated/DataFrame_generated.h:59:73: instantiated from 'static Rcpp::DataFrame Rcpp::DataFrame::create(const T1&, const T2&, const T3&, const T4&, const T5&, const T6&) [with T1 = Rcpp::traits::named_object >, T2 = Rcpp::traits::named_object >, T3 = Rcpp::traits::named_object >, T4 = Rcpp::traits::named_object >, T5 = Rcpp::traits::named_object >, T6 = Rcpp::traits::named_object >, Rcpp::DataFrame = Rcpp::DataFrame]' quotes.cpp:58:26: instantiated from here C:/R/R-3.0.1/library/Rcpp/include/Rcpp/internal/wrap.h:474:11: error: invalid conversion from 'long long int' to 'SEXP' [-fpermissive] make: * [quotes.o] Error 1 .
Is there a way to add a vector of this type into a DataFrame?
There is not, sadly, as CRAN only allows a C standard without long long.
Also, R itself only has numeric (aka double) and integer. So I would suggest you just use double as a type.
Related
I was trying to get the element with largest size from a vector of elements, as succinct as possible. The original code looks like,
std::cout << ((*std::max_element(rooms.begin(), rooms.end(),
[](auto a, auto b){a.size() < b.size();})).size()) << std::endl;
which g++ complains,
wall3.cpp: In function ‘int main()’:
wall3.cpp:150:47: error: ‘class __gnu_cxx::__normal_iterator<std::set<std::pair<long unsigned int, long unsigned int> >*, std::vector<std::set<std::pair<long unsigned int, long unsigned int> > > >’ has no member named ‘size’
150 | [](auto a, auto b){a.size() < b.size();}).size() << std::endl;
| ^~~~
In file included from /usr/include/c++/9/bits/stl_algobase.h:71,
from /usr/include/c++/9/bits/char_traits.h:39,
from /usr/include/c++/9/string:40,
from /usr/include/c++/9/bitset:47,
from wall3.cpp:1:
/usr/include/c++/9/bits/predefined_ops.h: In instantiation of ‘constexpr bool __gnu_cxx::__ops::_Iter_comp_iter<_Compare>::operator()(_Iterator1, _Iterator2) [with _Iterator1 = __gnu_cxx::__normal_iterator<std::set<std::pair<long unsigned int, long unsigned int> >*, std::vector<std::set<std::pair<long unsigned int, long unsigned int> > > >; _Iterator2 = __gnu_cxx::__normal_iterator<std::set<std::pair<long unsigned int, long unsigned int> >*, std::vector<std::set<std::pair<long unsigned int, long unsigned int> > > >; _Compare = main()::<lambda(auto:1, auto:2)>]’:
/usr/include/c++/9/bits/stl_algo.h:5692:12: required from ‘constexpr _ForwardIterator std::__max_element(_ForwardIterator, _ForwardIterator, _Compare) [with _ForwardIterator = __gnu_cxx::__normal_iterator<std::set<std::pair<long unsigned int, long unsigned int> >*, std::vector<std::set<std::pair<long unsigned int, long unsigned int> > > >; _Compare = __gnu_cxx::__ops::_Iter_comp_iter<main()::<lambda(auto:1, auto:2)> >]’
/usr/include/c++/9/bits/stl_algo.h:5743:43: required from ‘constexpr _FIter std::max_element(_FIter, _FIter, _Compare) [with _FIter = __gnu_cxx::__normal_iterator<std::set<std::pair<long unsigned int, long unsigned int> >*, std::vector<std::set<std::pair<long unsigned int, long unsigned int> > > >; _Compare = main()::<lambda(auto:1, auto:2)>]’
wall3.cpp:150:45: required from here
/usr/include/c++/9/bits/predefined_ops.h:143:18: error: void value not ignored as it ought to be
143 | { return bool(_M_comp(*__it1, *__it2)); }
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
It turns out that I forgot to use return in the lambda expression. Adding return solved the problem.
Lesson: use a different compiler and turn on the strictest warning configurations to reveal the problem faster. The output from clang++ is far more explicit,
wall3.cpp:150:33: warning: relational comparison result unused [-Wunused-comparison]
[](auto a, auto b){a.size() < b.size();})).size()) << std::endl;
~~~~~~~~~^~~~~~~~~~
This code is not my actual code, but just illustrates the issue. I have a rule that matches 0 or more digits, and an action that is supposed to count them and return that count as the synthesized attribute.
The attribute of *qi::ascii::digit should be a std::vector of the matched digits. So, I wrote the action so that it simply calls .size() and assigns the result to the synthesized attribute. To call .size(), I use boost.phoenix to bind a lambda that calls .size().
#include <boost/phoenix/bind/bind_function_object.hpp>
#include <boost/phoenix/core.hpp>
#include <boost/phoenix/operator.hpp>
#include <boost/spirit/include/qi.hpp>
#include <cstdint>
#include <iostream>
#include <string>
namespace phx = boost::phoenix;
namespace qi = boost::spirit::qi;
using It = std::string::iterator;
struct Parser : qi::grammar<std::string::iterator, size_t()> {
Parser() : Parser::base_type(r) {
auto count = [](auto&& v) { return v.size(); };
r %= (*qi::ascii::digit)[qi::_val = phx::bind(count, qi::_1)];
}
qi::rule<It, size_t()> r;
};
int main() {
using namespace std;
std::string s = "123";
int c;
Parser p;
qi::parse(s.begin(), s.end(), p, c);
std::cout << c << '\n';
}
But it doesn't work. I expect this code to compile and print 3. Instead, I get a very long compile error. The error is roughly what I would expect if the action were simply qi::_val = qi::_1, which perplexes me.
In file included from /usr/local/include/boost/type_traits/is_convertible.hpp:20,
from /usr/local/include/boost/type_traits/is_empty.hpp:12,
from /usr/local/include/boost/mpl/empty_base.hpp:23,
from /usr/local/include/boost/fusion/sequence/intrinsic/at.hpp:15,
from /usr/local/include/boost/phoenix/core/expression.hpp:11,
from /usr/local/include/boost/phoenix/bind/bind_function_object.hpp:17,
from spirit2.cpp:1:
/usr/local/include/boost/spirit/home/qi/parse.hpp: In instantiation of ‘bool boost::spirit::qi::parse(Iterator&, Iterator, const Expr&, Attr&) [with Iterator = __gnu_cxx::__normal_iterator<char*, std::__cxx11::basic_string<char> >; Expr = int; Attr = Parser]’:
/usr/local/include/boost/spirit/home/qi/parse.hpp:100:25: required from ‘bool boost::spirit::qi::parse(const Iterator&, Iterator, const Expr&, Attr&) [with Iterator = __gnu_cxx::__normal_iterator<char*, std::__cxx11::basic_string<char> >; Expr = int; Attr = Parser]’
spirit2.cpp:27:39: required from here
/usr/local/include/boost/spirit/home/qi/parse.hpp:85:9: error: static assertion failed: error_invalid_expression
BOOST_SPIRIT_ASSERT_MATCH(qi::domain, Expr);
^~~~~~~~~~~~~~~~~~~~~~~~~
In file included from /usr/local/include/boost/spirit/home/qi/detail/parse_auto.hpp:14,
from /usr/local/include/boost/spirit/home/qi/auto.hpp:16,
from /usr/local/include/boost/spirit/home/qi.hpp:15,
from /usr/local/include/boost/spirit/include/qi.hpp:16,
from spirit2.cpp:4:
/usr/local/include/boost/spirit/home/qi/parse.hpp:88:42: error: request for member ‘parse’ in ‘boost::spirit::compile<boost::spirit::qi::domain, int>((* & expr))’, which is of non-class type ‘boost::spirit::result_of::compile<boost::spirit::qi::domain, boost::proto::exprns_::expr<boost::proto::tagns_::tag::terminal, boost::proto::argsns_::term<int>, 0>, boost::spirit::unused_type, void>::type’ {aka ‘int’}
return compile<qi::domain>(expr).parse(first, last, context, unused, attr);
~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~
In file included from /usr/local/include/boost/spirit/home/qi/auxiliary/attr.hpp:18,
from /usr/local/include/boost/spirit/home/qi/auxiliary.hpp:19,
from /usr/local/include/boost/spirit/home/qi.hpp:16,
from /usr/local/include/boost/spirit/include/qi.hpp:16,
from spirit2.cpp:4:
/usr/local/include/boost/spirit/home/qi/detail/assign_to.hpp: In instantiation of ‘static void boost::spirit::traits::assign_to_attribute_from_value<Attribute, T, Enable>::call(const T_&, Attribute&, mpl_::false_) [with T_ = std::vector<char, std::allocator<char> >; Attribute = long unsigned int; T = std::vector<char, std::allocator<char> >; Enable = void; mpl_::false_ = mpl_::bool_<false>]’:
/usr/local/include/boost/spirit/home/qi/detail/assign_to.hpp:171:17: required from ‘static void boost::spirit::traits::assign_to_attribute_from_value<Attribute, T, Enable>::call(const T&, Attribute&) [with Attribute = long unsigned int; T = std::vector<char, std::allocator<char> >; Enable = void]’
/usr/local/include/boost/spirit/home/qi/detail/assign_to.hpp:370:63: required from ‘void boost::spirit::traits::detail::assign_to(const T&, Attribute&, mpl_::false_) [with T = std::vector<char, std::allocator<char> >; Attribute = long unsigned int; mpl_::false_ = mpl_::bool_<false>]’
/usr/local/include/boost/spirit/home/qi/detail/assign_to.hpp:393:26: required from ‘void boost::spirit::traits::assign_to(const T&, Attribute&) [with T = std::vector<char, std::allocator<char> >; Attribute = long unsigned int]’
/usr/local/include/boost/spirit/home/qi/detail/attributes.hpp:27:30: required from ‘static void boost::spirit::qi::default_transform_attribute<Exposed, Transformed>::post(Exposed&, const Transformed&) [with Exposed = long unsigned int; Transformed = std::vector<char, std::allocator<char> >]’
/usr/local/include/boost/spirit/home/qi/action/action.hpp:71:36: required from ‘bool boost::spirit::qi::action<Subject, Action>::parse(Iterator&, const Iterator&, Context&, const Skipper&, Attribute&) const [with Iterator = __gnu_cxx::__normal_iterator<char*, std::__cxx11::basic_string<char> >; Context = boost::spirit::context<boost::fusion::cons<long unsigned int&, boost::fusion::nil_>, boost::fusion::vector<> >; Skipper = boost::spirit::unused_type; Attribute = long unsigned int; Subject = boost::spirit::qi::kleene<boost::spirit::qi::char_class<boost::spirit::tag::char_code<boost::spirit::tag::digit, boost::spirit::char_encoding::ascii> > >; Action = boost::phoenix::actor<boost::proto::exprns_::basic_expr<boost::proto::tagns_::tag::assign, boost::proto::argsns_::list2<boost::phoenix::actor<boost::spirit::attribute<0> >, boost::phoenix::actor<boost::proto::exprns_::basic_expr<boost::phoenix::detail::tag::function_eval, boost::proto::argsns_::list2<boost::proto::exprns_::basic_expr<boost::proto::tagns_::tag::terminal, boost::proto::argsns_::term<Parser::Parser()::<lambda(auto:1&&)> >, 0>, boost::phoenix::actor<boost::spirit::argument<0> > >, 2> > >, 2> >]’
/usr/local/include/boost/spirit/home/qi/nonterminal/detail/parser_binder.hpp:73:54: [ skipping 3 instantiation contexts, use -ftemplate-backtrace-limit=0 to disable ]
/usr/local/include/boost/function/function_template.hpp:720:7: required from ‘boost::function4<R, T1, T2, T3, T4>::function4(Functor, typename boost::enable_if_<(! boost::is_integral<Functor>::value), int>::type) [with Functor = boost::spirit::qi::detail::parser_binder<boost::spirit::qi::action<boost::spirit::qi::kleene<boost::spirit::qi::char_class<boost::spirit::tag::char_code<boost::spirit::tag::digit, boost::spirit::char_encoding::ascii> > >, boost::phoenix::actor<boost::proto::exprns_::basic_expr<boost::proto::tagns_::tag::assign, boost::proto::argsns_::list2<boost::phoenix::actor<boost::spirit::attribute<0> >, boost::phoenix::actor<boost::proto::exprns_::basic_expr<boost::phoenix::detail::tag::function_eval, boost::proto::argsns_::list2<boost::proto::exprns_::basic_expr<boost::proto::tagns_::tag::terminal, boost::proto::argsns_::term<Parser::Parser()::<lambda(auto:1&&)> >, 0>, boost::phoenix::actor<boost::spirit::argument<0> > >, 2> > >, 2> > >, mpl_::bool_<true> >; R = bool; T0 = __gnu_cxx::__normal_iterator<char*, std::__cxx11::basic_string<char> >&; T1 = const __gnu_cxx::__normal_iterator<char*, std::__cxx11::basic_string<char> >&; T2 = boost::spirit::context<boost::fusion::cons<long unsigned int&, boost::fusion::nil_>, boost::fusion::vector<> >&; T3 = const boost::spirit::unused_type&; typename boost::enable_if_<(! boost::is_integral<Functor>::value), int>::type = int]’
/usr/local/include/boost/function/function_template.hpp:1068:16: required from ‘boost::function<R(T0, T1, T2, T3)>::function(Functor, typename boost::enable_if_<(! boost::is_integral<Functor>::value), int>::type) [with Functor = boost::spirit::qi::detail::parser_binder<boost::spirit::qi::action<boost::spirit::qi::kleene<boost::spirit::qi::char_class<boost::spirit::tag::char_code<boost::spirit::tag::digit, boost::spirit::char_encoding::ascii> > >, boost::phoenix::actor<boost::proto::exprns_::basic_expr<boost::proto::tagns_::tag::assign, boost::proto::argsns_::list2<boost::phoenix::actor<boost::spirit::attribute<0> >, boost::phoenix::actor<boost::proto::exprns_::basic_expr<boost::phoenix::detail::tag::function_eval, boost::proto::argsns_::list2<boost::proto::exprns_::basic_expr<boost::proto::tagns_::tag::terminal, boost::proto::argsns_::term<Parser::Parser()::<lambda(auto:1&&)> >, 0>, boost::phoenix::actor<boost::spirit::argument<0> > >, 2> > >, 2> > >, mpl_::bool_<true> >; R = bool; T0 = __gnu_cxx::__normal_iterator<char*, std::__cxx11::basic_string<char> >&; T1 = const __gnu_cxx::__normal_iterator<char*, std::__cxx11::basic_string<char> >&; T2 = boost::spirit::context<boost::fusion::cons<long unsigned int&, boost::fusion::nil_>, boost::fusion::vector<> >&; T3 = const boost::spirit::unused_type&; typename boost::enable_if_<(! boost::is_integral<Functor>::value), int>::type = int]’
/usr/local/include/boost/function/function_template.hpp:1121:5: required from ‘typename boost::enable_if_<(! boost::is_integral<Functor>::value), boost::function<R(T0, T1, T2, T3)>&>::type boost::function<R(T0, T1, T2, T3)>::operator=(Functor) [with Functor = boost::spirit::qi::detail::parser_binder<boost::spirit::qi::action<boost::spirit::qi::kleene<boost::spirit::qi::char_class<boost::spirit::tag::char_code<boost::spirit::tag::digit, boost::spirit::char_encoding::ascii> > >, boost::phoenix::actor<boost::proto::exprns_::basic_expr<boost::proto::tagns_::tag::assign, boost::proto::argsns_::list2<boost::phoenix::actor<boost::spirit::attribute<0> >, boost::phoenix::actor<boost::proto::exprns_::basic_expr<boost::phoenix::detail::tag::function_eval, boost::proto::argsns_::list2<boost::proto::exprns_::basic_expr<boost::proto::tagns_::tag::terminal, boost::proto::argsns_::term<Parser::Parser()::<lambda(auto:1&&)> >, 0>, boost::phoenix::actor<boost::spirit::argument<0> > >, 2> > >, 2> > >, mpl_::bool_<true> >; R = bool; T0 = __gnu_cxx::__normal_iterator<char*, std::__cxx11::basic_string<char> >&; T1 = const __gnu_cxx::__normal_iterator<char*, std::__cxx11::basic_string<char> >&; T2 = boost::spirit::context<boost::fusion::cons<long unsigned int&, boost::fusion::nil_>, boost::fusion::vector<> >&; T3 = const boost::spirit::unused_type&; typename boost::enable_if_<(! boost::is_integral<Functor>::value), boost::function<R(T0, T1, T2, T3)>&>::type = boost::function<bool(__gnu_cxx::__normal_iterator<char*, std::__cxx11::basic_string<char> >&, const __gnu_cxx::__normal_iterator<char*, std::__cxx11::basic_string<char> >&, boost::spirit::context<boost::fusion::cons<long unsigned int&, boost::fusion::nil_>, boost::fusion::vector<> >&, const boost::spirit::unused_type&)>&]’
/usr/local/include/boost/spirit/home/qi/nonterminal/rule.hpp:185:19: required from ‘static void boost::spirit::qi::rule<Iterator, T1, T2, T3, T4>::define(boost::spirit::qi::rule<Iterator, T1, T2, T3, T4>&, const Expr&, mpl_::true_) [with Auto = mpl_::bool_<true>; Expr = boost::proto::exprns_::expr<boost::proto::tagns_::tag::subscript, boost::proto::argsns_::list2<const boost::proto::exprns_::expr<boost::proto::tagns_::tag::dereference, boost::proto::argsns_::list1<const boost::proto::exprns_::expr<boost::proto::tagns_::tag::terminal, boost::proto::argsns_::term<boost::spirit::tag::char_code<boost::spirit::tag::digit, boost::spirit::char_encoding::ascii> >, 0>&>, 1>&, const boost::phoenix::actor<boost::proto::exprns_::basic_expr<boost::proto::tagns_::tag::assign, boost::proto::argsns_::list2<boost::phoenix::actor<boost::spirit::attribute<0> >, boost::phoenix::actor<boost::proto::exprns_::basic_expr<boost::phoenix::detail::tag::function_eval, boost::proto::argsns_::list2<boost::proto::exprns_::basic_expr<boost::proto::tagns_::tag::terminal, boost::proto::argsns_::term<Parser::Parser()::<lambda(auto:1&&)> >, 0>, boost::phoenix::actor<boost::spirit::argument<0> > >, 2> > >, 2> >&>, 2>; Iterator = __gnu_cxx::__normal_iterator<char*, std::__cxx11::basic_string<char> >; T1 = long unsigned int(); T2 = boost::spirit::unused_type; T3 = boost::spirit::unused_type; T4 = boost::spirit::unused_type; mpl_::true_ = mpl_::bool_<true>]’
/usr/local/include/boost/spirit/home/qi/nonterminal/rule.hpp:249:31: required from ‘boost::spirit::qi::rule<Iterator, T1, T2, T3, T4>& boost::spirit::qi::operator%=(boost::spirit::qi::rule<Iterator, T1, T2, T3, T4>&, Expr&&) [with Expr = const boost::proto::exprns_::expr<boost::proto::tagns_::tag::subscript, boost::proto::argsns_::list2<const boost::proto::exprns_::expr<boost::proto::tagns_::tag::dereference, boost::proto::argsns_::list1<const boost::proto::exprns_::expr<boost::proto::tagns_::tag::terminal, boost::proto::argsns_::term<boost::spirit::tag::char_code<boost::spirit::tag::digit, boost::spirit::char_encoding::ascii> >, 0>&>, 1>&, const boost::phoenix::actor<boost::proto::exprns_::basic_expr<boost::proto::tagns_::tag::assign, boost::proto::argsns_::list2<boost::phoenix::actor<boost::spirit::attribute<0> >, boost::phoenix::actor<boost::proto::exprns_::basic_expr<boost::phoenix::detail::tag::function_eval, boost::proto::argsns_::list2<boost::proto::exprns_::basic_expr<boost::proto::tagns_::tag::terminal, boost::proto::argsns_::term<Parser::Parser()::<lambda(auto:1&&)> >, 0>, boost::phoenix::actor<boost::spirit::argument<0> > >, 2> > >, 2> >&>, 2>; Iterator = __gnu_cxx::__normal_iterator<char*, std::__cxx11::basic_string<char> >; T1 = long unsigned int(); T2 = boost::spirit::unused_type; T3 = boost::spirit::unused_type; T4 = boost::spirit::unused_type]’
spirit2.cpp:16:69: required from here
/usr/local/include/boost/spirit/home/qi/detail/assign_to.hpp:153:20: error: invalid static_cast from type ‘const std::vector<char, std::allocator<char> >’ to type ‘long unsigned int’
attr = static_cast<Attribute>(val);
^~~~~~~~~~~~~~~~~~~~~~~~~~~
The solution is to drop %:
r = (*qi::ascii::digit)[qi::_val = phx::bind(count, qi::_1)];
The important error message is in the last line: error: invalid static_cast from type ‘const std::vector<char, std::allocator<char> >’ to type ‘long unsigned int’
For why it produces vector<char> see here.
There is use of semantic action and:
r %= p and r = p are equivalent if there are no semantic actions
associated with p.
Read more about it here.
The doqtor did an excellent job of introducing the relevant concepts. I'd just like to show some simplification if you have a recent compiler (which it looks like you do):
phx::function count { [](auto&& v) { return v.size(); } };
r = (*digit)[_val = count(_1)];
Live On Coliru
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix.hpp>
namespace phx = boost::phoenix;
namespace qi = boost::spirit::qi;
using It = std::string::const_iterator;
struct Parser : qi::grammar<It, size_t()> {
Parser() : Parser::base_type(r) {
using namespace qi;
phx::function count { [](auto&& v) { return v.size(); } };
r = (*digit)[_val = count(_1)];
}
private:
qi::rule<It, size_t()> r;
};
int main() {
std::string const s = "123";
int c;
Parser p;
if (qi::parse(s.begin(), s.end(), p, c)) {
std::cout << "Number of digits: " << c << "\n";
}
}
Prints
Number of digits: 3
Why does one variant assignment compile while the other does not? The template instances do not share any types and char could be converted to int, say. What is boost::variant trying to do, that it cannot do in the case of the first assignment and that it can do in the case of the second assignment? Error is below.
#include <string>
#include "boost/variant.hpp"
int main()
{
boost::variant<char> v1;
boost::variant<std::string, int, double> v2;
v1 = v2; // compile error
v2 = v1; // compiles fine
return 0;
}
In file included from /usr/include/boost/variant.hpp:17:0,
from v.cpp:3:
/usr/include/boost/variant/variant.hpp: In instantiation of 'int boost::variant<T0, TN>::convert_copy_into::internal_visit(T&, int) const [with T = const std::basic_string<char>; T0_ = char; TN = {}]':
/usr/include/boost/variant/detail/visitation_impl.hpp:113:9: required from 'typename Visitor::result_type boost::detail::variant::visitation_impl_invoke_impl(int, Visitor&, VoidPtrCV, T*, mpl_::true_) [with Visitor = boost::variant<char>::convert_copy_into; VoidPtrCV = const void*; T = std::basic_string<char>; typename Visitor::result_type = int; mpl_::true_ = mpl_::bool_<true>]'
/usr/include/boost/variant/detail/visitation_impl.hpp:156:9: required from 'typename Visitor::result_type boost::detail::variant::visitation_impl_invoke(int, Visitor&, VoidPtrCV, T*, NoBackupFlag, int) [with Visitor = boost::variant<char>::convert_copy_into; VoidPtrCV = const void*; T = std::basic_string<char>; NoBackupFlag = boost::variant<std::basic_string<char>, int, double>::has_fallback_type_; typename Visitor::result_type = int]'
/usr/include/boost/variant/detail/visitation_impl.hpp:237:5: required from '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::l_iter<boost::mpl::l_item<mpl_::long_<3l>, std::basic_string<char>, boost::mpl::l_item<mpl_::long_<2l>, int, boost::mpl::l_item<mpl_::long_<1l>, double, boost::mpl::l_end> > > >, boost::mpl::l_iter<boost::mpl::l_end> >; Visitor = boost::variant<char>::convert_copy_into; VoidPtrCV = const void*; NoBackupFlag = boost::variant<std::basic_string<char>, int, double>::has_fallback_type_; typename Visitor::result_type = int; mpl_::false_ = mpl_::bool_<false>]'
/usr/include/boost/variant/variant.hpp:2245:13: required from 'static typename Visitor::result_type boost::variant<T0, TN>::internal_apply_visitor_impl(int, int, Visitor&, VoidPtrCV) [with Visitor = boost::variant<char>::convert_copy_into; VoidPtrCV = const void*; T0_ = std::basic_string<char>; TN = {int, double}; typename Visitor::result_type = int]'
/usr/include/boost/variant/variant.hpp:2267:13: [ skipping 2 instantiation contexts, use -ftemplate-backtrace-limit=0 to disable ]
/usr/include/boost/variant/variant.hpp:1581:13: required from 'void boost::variant<T0, TN>::convert_construct_variant(Variant&) [with Variant = const boost::variant<std::basic_string<char>, int, double>; T0_ = char; TN = {}]'
/usr/include/boost/variant/variant.hpp:1628:42: required from 'void boost::variant<T0, TN>::convert_construct(const boost::variant<U0, UN ...>&, long int) [with U0 = std::basic_string<char>; UN = {int, double}; T0_ = char; TN = {}]'
/usr/include/boost/variant/variant.hpp:1649:38: required from 'boost::variant<T0, TN>::variant(const T&) [with T = boost::variant<std::basic_string<char>, int, double>; T0_ = char; TN = {}]'
/usr/include/boost/variant/variant.hpp:2059:29: required from 'void boost::variant<T0, TN>::assign(const T&) [with T = boost::variant<std::basic_string<char>, int, double>; T0_ = char; TN = {}]'
/usr/include/boost/variant/variant.hpp:2099:19: required from 'boost::variant<T0, TN>& boost::variant<T0, TN>::operator=(const T&) [with T = boost::variant<std::basic_string<char>, int, double>; T0_ = char; TN = {}]'
v.cpp:10:6: required from here
/usr/include/boost/variant/variant.hpp:1366:61: error: no matching function for call to 'boost::variant<char>::initializer::initialize(void* const&, const std::basic_string<char>&)'
return initializer::initialize(storage_, operand);
^
/usr/include/boost/variant/variant.hpp:1366:61: note: candidates are:
In file included from /usr/include/boost/variant/variant.hpp:32:0,
from /usr/include/boost/variant.hpp:17,
from v.cpp:3:
/usr/include/boost/variant/detail/initializer.hpp:104:24: note: static int boost::detail::variant::make_initializer_node::apply<BaseIndexPair, Iterator>::initializer_node::initialize(void*, boost::detail::variant::make_initializer_node::apply<BaseIndexPair, Iterator>::initializer_node::param_T) [with BaseIndexPair = boost::mpl::pair<boost::detail::variant::initializer_root, mpl_::int_<0> >; Iterator = boost::mpl::l_iter<boost::mpl::list1<char> >; boost::detail::variant::make_initializer_node::apply<BaseIndexPair, Iterator>::initializer_node::param_T = const char&]
static int initialize(void* dest, param_T operand)
^
/usr/include/boost/variant/detail/initializer.hpp:104:24: note: no known conversion for argument 2 from 'const std::basic_string<char>' to 'boost::detail::variant::make_initializer_node::apply<boost::mpl::pair<boost::detail::variant::initializer_root, mpl_::int_<0> >, boost::mpl::l_iter<boost::mpl::list1<char> > >::initializer_node::param_T {aka const char&}'
/usr/include/boost/variant/detail/initializer.hpp:115:24: note: static int boost::detail::variant::make_initializer_node::apply<BaseIndexPair, Iterator>::initializer_node::initialize(void*, boost::detail::variant::make_initializer_node::apply<BaseIndexPair, Iterator>::initializer_node::param2_T) [with BaseIndexPair = boost::mpl::pair<boost::detail::variant::initializer_root, mpl_::int_<0> >; Iterator = boost::mpl::l_iter<boost::mpl::list1<char> >; boost::detail::variant::make_initializer_node::apply<BaseIndexPair, Iterator>::initializer_node::param2_T = char&&]
static int initialize(void* dest, param2_T operand)
^
/usr/include/boost/variant/detail/initializer.hpp:115:24: note: no known conversion for argument 2 from 'const std::basic_string<char>' to 'boost::detail::variant::make_initializer_node::apply<boost::mpl::pair<boost::detail::variant::initializer_root, mpl_::int_<0> >, boost::mpl::l_iter<boost::mpl::list1<char> > >::initializer_node::param2_T {aka char&&}'
/usr/include/boost/variant/detail/initializer.hpp:149:17: note: static void boost::detail::variant::initializer_root::initialize()
static void initialize();
^
/usr/include/boost/variant/detail/initializer.hpp:149:17: note: candidate expects 0 arguments, 2 provided
A char definitely can be stored in an int but the converse is not always true. Therefore the one that fails to compile would be unsafe at runtime, so you're probably better off with it failing. Cast the int to a char if you must.
I'm have the following elements:
#define TEMPLATE_PARAM boost::variant<int, const std::string&, const std::vector<std::string>&, const std::vector<int>&, const ITemplateLoop*, const std::vector<ITemplateLoop*>&>
class PostParam
{
...
const std::string &getParam() const;
};
class ParamContainer
{
std::map<std::string, TEMPLATE_PARAM> map_;
template <typename T>
void insert(std::string key, const T & value)
{
map_[key] = value;
}
public:
template<typename ... Args>
void add(std::map<std::string, std::shared_ptr<PostParam>>& param, Args ... args)
{
for (const auto & key : param)
insert(key.first, key.second->getParam());
if (sizeof ...(Args) > 0)
add(args...);
}
I am getting a lot of compilation error and I don't know what to paste here
/usr/local/include/boost/detail/reference_content.hpp: In member function 'void boost::detail::variant::move_storage::internal_visit(T&, int) const [with T = boost::de tail::reference_content<const std::basic_string<char>&>]':
/usr/local/include/boost/variant/detail/visitation_impl.hpp:130:9: instantiated from 'typename Visitor::result_type boost::detail::variant::visitation_impl_invoke_impl(int, Visitor&, VoidPtrCV, T*, mpl_::true_) [with Visitor = boost::detail::variant::move_storage, VoidPtrCV = void*, T = boost::detail::reference_content<const std::basic_string<char>&>, typename Visitor::result_type = void, mpl_::true_ = mpl_::bool_<true>]'
/usr/local/include/boost/variant/detail/visitation_impl.hpp:173:9: instantiated from 'typename Visitor::result_type boost::detail::variant::visitation_impl_invoke(int, Visitor&, VoidPtrCV, T*, NoBackupFlag, int) [with Visitor=boost::detail::variant::move_storage, VoidPtrCV = void*, T = boost::detail::reference_content<const std::basic_string<char>&>, NoBackupFlag = boost::variant<int, const std::basic_string<char>&, const std::vector<std::basic_string<char> >&, const std::vector<int>&, const TemplateEngine::ITemplateLoop*, const std::vector<TemplateEngine::ITemplateLoop*>&, const PostParam&>::has_fallback_type_, typename Visitor::result_type = void]'
/usr/local/include/boost/variant/detail/visitation_impl.hpp:260:1: instantiated from '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::l_iter< boost::mpl::l_item<mpl_::long_<7l>, int, boost::mpl::l_item<mpl_::long_<6l>, boost::detail::reference_content<const std::basic_string<char>&>, boost::mpl::l_item<mpl_: :long_<5l>, boost::detail::reference_content<const std::vector<std::basic_string<char> >&>, boost::mpl::l_item<mpl_::long_<4l>, boost::detail::reference_content<const std::vector<int>&>, boost::mpl::l_item<mpl_::long_<3l>, const TemplateEngine::ITemplateLoop*, boost::mpl::l_item<mpl_::long_<2l>, boost::detail::reference_content<const std::vector<TemplateEngine::ITemplateLoop*>&>, boost::mpl::l_item<mpl_::long_<1l>, boost::detail::reference_content<const PostParam&>, boost::mpl::l_end> > > > > > > >, boost::mpl::l_iter<boost::mpl::l_end> >, Visitor = boost::detail::variant::move_storage, VoidPtrCV = void*, NoBackupFlag = boost::variant<int, const std::basic_string<char>&, const std::vector<std::basic_string<char> >&, const std::vector<int>&, const TemplateEngine::ITemplateLoop*, const std::vector<TemplateEngine::ITemplateLoop*>&, const PostParam&>::has_fallback_type_, typename Visitor::result_type = void, mpl_::false_ = mpl_::bool_<false>]'
I think it's the parameter that I get using key.second->getParam() but I'm unable to find a solution
Edit
I have changed the #define to the typedef
So the error message
/home/django/cloaked-ninja/includes/TemplateEngine.hpp:67:7: instantiated from 'void TemplateEngine::ParamContainer::insert(std::string, const T&) [with T = std::basic_string<char>, std::string = std::basic_string<char>]'
/home/django/cloaked-ninja/includes/TemplateEngine.hpp:94:2: instantiated from 'void TemplateEngine::ParamContainer::add(std::map<std::basic_string<char>, std::shared_ptr<PostParam> >&, Args ...) [with Args = {}]'
/home/django/cloaked-ninja/src/Controller/ControllerPost.cpp:22:14: instantiated from here
/usr/local/include/boost/detail/reference_content.hpp:62:24: error: 'boost::detail::reference_content<RefT>& boost::detail::reference_content<RefT>::operator=(const boost::detail::reference_content<RefT>&) [with RefT = const std::basic_string<char>&, boost::detail::reference_content<RefT> = boost::detail::reference_content<const std::basic_string<char>&>]' is private
/usr/local/include/boost/variant/variant.hpp:583:9: error: within this context
/usr/local/include/boost/detail/reference_content.hpp: In member function 'void boost::detail::variant::move_storage::internal_visit(T&, int) const [with T = boost::de tail::reference_content<const std::vector<std::basic_string<char> >&>]':
/usr/local/include/boost/variant/detail/visitation_impl.hpp:130:9: instantiated from 'typename Visitor::result_type boost::detail::variant::visitation_impl_invoke_impl(int, Visitor&, VoidPtrCV, T*, mpl_::true_) [with Visitor = boost::detail::variant::move_storage, VoidPtrCV = void*, T = boost::detail::reference_content<const std::vector<std::basic_string<char> >&>, typename Visitor::result_type = void, mpl_::true_ = mpl_::bool_<true>]'
/usr/local/include/boost/detail/reference_content.hpp: In member function 'void boost::detail::variant::move_storage::internal_visit(T&, int) const [with T = boost::detail::reference_content<const std::vector<std::basic_string<char> >&>]':
/usr/local/include/boost/variant/detail/visitation_impl.hpp:130:9: instantiated from 'typename Visitor::result_type boost::detail::variant::visitation_impl_invoke_impl(int, Visitor&, VoidPtrCV, T*, mpl_::true_) [with Visitor = boost::detail::variant::move_storage, VoidPtrCV = void*, T = boost::detail::reference_content<const
std::vector<std::basic_string<char> >&>, typename Visitor::result_type = void, mpl_::true_ = mpl_::bool_<true>]'
/usr/local/include/boost/variant/detail/visitation_impl.hpp:173:9: instantiated from 'typename Visitor::result_type boost::detail::variant::visitation_impl_invoke(int, Visitor&, VoidPtrCV, T*, NoBackupFlag, int) [with Visitor = boost::detail::variant::move_storage, VoidPtrCV = void*, T = boost::detail::reference_content<const std::vector<std::basic_string<char> >&>, NoBackupFlag = boost::variant<int, const std::basic_string<char>&, const std::vector<std::basic_string<char> >&, const std::vector<int>&, const TemplateEngine::ITemplateLoop*, const std::vector<TemplateEngine::ITemplateLoop*>&>::has_fallback_type_, typename Visitor::result_type = void]'
/usr/local/include/boost/variant/detail/visitation_impl.hpp:260:1: instantiated from '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::l_iter<boost::mpl::l_item<mpl_::long_<6l>, int, boost::mpl::l_item<mpl_::long_<5l>, boost::detail::reference_content<const std::basic_string<char>&>, boost::mpl::l_item<mpl_::long_<4l>, boost::detail::reference_content<const std::vector<std::basic_string<char> >&>, boost::mpl::l_item<mpl_::long_<3l>, boost::detail::reference_content<const std::vector<int>&>, boost::mpl::l_item<mpl_::long_<2l>, const TemplateEngine::ITemplateLoop*, boost::mpl::l_item<mpl_::long_<1l>, boost::detail::reference_content<const std::vector<TemplateEngine::ITemplateLoop*>&>, boost::mpl::l_end> > > > > > >, boost::mpl::l_iter<boost::mpl::l_end> >, Visitor = boost::detail::variant::move_storage, VoidPtrCV = void*, NoBackupFlag = boost::variant<int, const std::basic_string<char>&, const std::vector<std::basic_string<char> >&, const std::vector<int>&, const TemplateEngine::ITemplateLoop*, const std::vector<TemplateEngine::ITemplateLoop*>&>::has_fallback_type_, typename Visitor::result_type = void, mpl_::false_ = mpl_::bool_<false>]'
Edit2
I have just changed the #define to the following typedef and it's now working:
typedef boost::variant<int, const std::string*, const std::vector<std::string>*, const std::vector<int>*, const ITemplateLoop*, const std::vector<ITemplateLoop*>*> TEMPLATE_PARAM;
If I'm not completely mistaken, the problem lies within your variant declaration. boost::variant can not take values as const &, because a copy of the data is required.
Here is a minimal working example:
#include <boost/variant.hpp>
#include <string>
#include <map>
struct foo
{
typedef boost::variant<int, std::string> variant;
std::map<std::string, variant> map;
template <typename T>
void insert(std::string const & key, T const & value)
{
map[key] = value;
}
};
int main()
{
foo f;
f.insert("test", "foo");
return 0;
}
std::multimap<size_type,size_type>::iterator it;
std::multimap<size_type,size_type>::iterator itlow = colToRow.lower_bound(cols[i]);
std::multimap<size_type,size_type>::iterator itup = colToRow.upper_bound(cols[i]);
if((it = std::find(itlow,itup,std::pair<size_type,size_type>(cols[i],b))) != itup)
Why does this keep giving me an error, cols[i] and b are both of size type and when I insert into the multimap, it has no problem of inserting it as a pair, how else can this be done?
Thank you,
The error:
/usr/include/c++/4.3/bits/stl_algo.h: In function '_InputIterator std::__find(_InputIterator, _InputIterator, const _Tp&, std::input_iterator_tag) [with _InputIterator = std::_Rb_tree_iterator<std::pair<const unsigned int, unsigned int> >, _Tp = std::pair<unsigned int, unsigned int>]':
/usr/include/c++/4.3/bits/stl_algo.h:3814: instantiated from '_IIter std::find(_IIter, _IIter, const _Tp&) [with _IIter = std::_Rb_tree_iterator<std::pair<const unsigned int, unsigned int> >, _Tp = std::pair<unsigned int, unsigned int>]'
SMatrix.cpp:286: instantiated from here
/usr/include/c++/4.3/bits/stl_algo.h:151: error: no match for 'operator==' in '__first.std::_Rb_tree_iterator<_Tp>::operator* [with _Tp = std::pair<const unsigned int, unsigned int>]() == __val'
The value_type of a multimap<size_type, size_type> is a std::pair<size_type const,size_type>, rather than a std::pair<size_type,size_type>.
You are trying to find a std::pair<size_type,size_type>, but this cannot be compared to a std::pair<size_type const,size_type>.
Try:
if((it = std::find(itlow,itup,std::pair<const size_type,size_type>(cols[i],b))) != itup)
// ^^^^^
Due to the hint from this error:
error: no match for 'operator==' in '__first.std::_Rb_tree_iterator<_Tp>::operator*
[with _Tp = std::pair<const unsigned int, unsigned int>]() == __val'
// ^^^^^^^^^^^^^^^^^^