#5455 closed Bugs (wontfix)
std::vector<byte_> not assignable to std::vector<unsigned char>
Reported by: | Owned by: | Hartmut Kaiser | |
---|---|---|---|
Milestone: | To Be Determined | Component: | spirit |
Version: | Boost 1.44.0 | Severity: | Problem |
Keywords: | Cc: |
Description
Using a rule that is like this:
rule = (*qi::byte_) [at_c<0>(_val) = _1];
where _val is a fusion-adapted struct that has a member (std::vector<uint8_t>, data).
I get an error that there is no viable overload of operator= for:
BOOST_BINARY_RESULT_OF(x = y, result_of_assign)
where x = std::vector<unsigned char, std::allocator<unsigned char> > and y = std::vector<boost::integer::endian<2, unsigned char, 8, 0>, std::allocator<boost::integer::endian<2, unsigned char, 8, 0> > >
appears to occur in this instantiation:
boost::phoenix::result_of_assign<std::vector<unsigned char, std::allocator<unsigned char> > &, std::vector<boost::integer::endian<2, unsigned char, 8, 0>, std::allocator<boost::integer::endian<2, unsigned char, 8, 0> > > &>
Change History (7)
comment:1 by , 12 years ago
comment:2 by , 12 years ago
#include <boost/fusion/container/vector.hpp> #include <boost/fusion/adapted/struct/define_struct.hpp> #include <boost/spirit/include/phoenix.hpp> #include <boost/spirit/include/qi.hpp> #include <vector> BOOST_FUSION_DEFINE_STRUCT( (), Vector, (std::vector<unsigned char>, v)) BOOST_FUSION_DEFINE_STRUCT( (), Byte, (unsigned char, b)) int main(int argc, char * argv[]) { using namespace boost::spirit::qi; using namespace boost::phoenix; /* r1 compiles fine: byte_ assigns to unsigned char */ rule<char const *, Byte()> r1; r1 = byte_ [at_c<0>(_val)=_1]; /* r2 does not compile: vector<byte_> does not assign to vector<unsigned char> */ rule<char const *, Vector()> r2; r2 = (*byte_) [at_c<0>(_val)=_1]; return 0; }
comment:3 by , 12 years ago
Owner: | changed from | to
---|
Doesn't look like a bug to me. It's the same as trying to assign a vector<boost::integer::endian<2, unsigned char, 8, 0> > from a vector<unsigned char>.
I'll forward to Hartmut Kaiser anyway. He's the author of the binary parsers.
comment:4 by , 12 years ago
Joel is right, it just can't work the way you set it up. And there is no way for Spirit to figure out how to convert the two vectors. But why do you need to use semantic actions? If you were relying on Spirit's attribute propagation it would be possible to make it work:
r2 = (*byte_) >> eps;
compiles just fine and does what you expect.
comment:5 by , 12 years ago
Resolution: | → wontfix |
---|---|
Status: | new → closed |
comment:6 by , 12 years ago
It just seems odd that all these work:
U = T U %= T std::vector<U> %= (*T) at_c<n>(U) = T
but this fails:
at_c<n>(std::vector<U>) = std::vector<T>
I was able to work around the issue by using phx::assign, but it just seems inconsistent, especially since there doesnt appear to be any useful way to combine at_c with a vector of byte_'s (std::vector<boost::integer::endian<2, unsigned char, 8, 0> just doesnt seem to be the right way to do it, and it looks like that should be convertible to std::vector<unsigned char>). But, if it's "wontfix", I'll let it go. Thanks.
comment:7 by , 12 years ago
That std::vector<U> cannot be assigned to std::vector<T> is not the problem of Spirit but is the problem of the C++ standard library -which is beyond the scope of what we can do. I suggest what Hartmut mentioned: use attribute propagation. There, we have more control of what we can do for ease of use.
Why is this a bug? Please provide a minimal cpp file I can try. Also see Spirit support: http://boost-spirit.com/home/feedback-and-support/