Opened 9 years ago
Closed 9 years ago
#9840 closed Bugs (invalid)
phoenix V3 and stl container non const methods
Reported by: | Owned by: | Thomas Heller | |
---|---|---|---|
Milestone: | To Be Determined | Component: | phoenix |
Version: | Boost 1.53.0 | Severity: | Problem |
Keywords: | stl container method | Cc: |
Description
I'm using boost 1.53 (boost-devel-1.53.0-6.fc19.i686). I think I found a bug with phoenix and stl methods. It looks like boost assumes that all methods are const which is not true (eg vector::reserve).
I tried to change:
#define BOOST_PHOENIX_ADAPT_CALLABLE(NAME, FUNC, N) \ template <BOOST_PHOENIX_typename_A(N)> \ inline \ typename \ boost::phoenix::detail::expression::function_eval< \ FUNC \ , BOOST_PHOENIX_A(N)>::type const \ NAME(BOOST_PHOENIX_A_const_ref_a(N)) \ { \ return boost::phoenix::detail::expression:: \ function_eval<FUNC, BOOST_PHOENIX_A(N)>:: \ make(FUNC(), BOOST_PHOENIX_a(N)); \ } \
into
#define BOOST_PHOENIX_ADAPT_CALLABLE(NAME, FUNC, N) \ template <BOOST_PHOENIX_typename_A(N)> \ inline \ typename \ boost::phoenix::detail::expression::function_eval< \ FUNC \ , BOOST_PHOENIX_A(N)>::type const \ NAME(BOOST_PHOENIX_A_ref_a(N)) \ { \ return boost::phoenix::detail::expression:: \ function_eval<FUNC, BOOST_PHOENIX_A(N)>:: \ make(FUNC(), BOOST_PHOENIX_a(N)); \ } \
but that's not enough. That part of the problem remains in git. But that is not sufficient, some other method in the chain imposes constness.
phoenix should not try to impose constness IMHO, the chain of instantiations should just pass the orginal type...
Here is a (not totally simplified as it uses spirit) example to reproduce the problem:
#include <boost/spirit/include/qi.hpp> #include <boost/spirit/include/phoenix.hpp> #include <boost/phoenix/stl.hpp> #include <boost/spirit/include/qi_uint.hpp> #include <boost/phoenix/phoenix.hpp> std::vector<unsigned> L; int main() { using namespace boost::spirit::qi; using namespace boost::phoenix; using boost::phoenix::arg_names::_1; const std::string str("3 1 2 3"); std::string::const_iterator first = str.begin(); parse(first,str.end(), uint_[reserve(L,_1)] >> repeat(capacity(L))[ uint_ ]); }
Attachments (1)
Change History (6)
by , 9 years ago
comment:1 by , 9 years ago
I forgot, this is to be compiled with:
g++ -DBOOST_SPIRIT_USE_PHOENIX_V3 test.C
comment:2 by , 9 years ago
Please post a test cpp file that does not use Spirit. A phoenix-only test will make it clear that this is a phoenix bug, if it is indeed a bug.
comment:3 by , 9 years ago
I cannot, I tried some obvious code, but I do not know phoenix much. Can you requalify it as a spirit bug ?
comment:4 by , 9 years ago
Wait, I see the problem and it's not a phoenix bug nor a spirit bug. It's a usage bug.
1) L is captured by value, by default. Use ref if you want to capture by reference 2) Use boost::spirit::qi::_1 instead of boost::phoenix::arg_names::_1
Here's the working code:
#include <boost/spirit/include/qi.hpp> #include <boost/spirit/include/phoenix.hpp> #include <boost/phoenix/stl.hpp> #include <boost/spirit/include/qi_uint.hpp> #include <boost/phoenix/phoenix.hpp> std::vector<unsigned> L; int main() { using namespace boost::spirit::qi; using namespace boost::phoenix; using boost::spirit::qi::_1; namespace phx = boost::phoenix; const std::string str("3 1 2 3"); std::string::const_iterator first = str.begin(); parse(first,str.end(), uint_[reserve(phx::ref(L),_1)] >> repeat(capacity(phx::cref(L)))[ uint_ ]); }
I'll leave it up to you to close this ticket.
comment:5 by , 9 years ago
Resolution: | → invalid |
---|---|
Status: | new → closed |
I'm closing this one. Feel free to re-open if you have objections.
File to reproduce the problem