I encounter this error while using emplace_back to construct a bit field structure in a vector:
struct Foo
{
Foo(uint32_t foo1): foo1(foo1) {}
uint32_t foo1 : 4;
};
int main()
{
vector<Foo> fooVector;
Foo foo = Foo(10);
fooVector.emplace_back(foo.foo1); // Error: non-const reference cannot bind to bit-field
}
I have found that I can avoid this error by either using push_back (but I prefer emplace_back for performance reasons), or by modifying the concerned line like so:
fooVector.emplace_back(uint32_t(foo.foo1)); // Don't raise error
Is it the proper way to deal with it? Why does this solution work?
CodePudding user response:
This is the definition of std::vector::emplace_back
:
template< class... Args >
reference emplace_back( Args&&... args );
Args&&
in this case gets deduced to uint32_t&
, and, as the error says, a bit-field (Foo::foo1
) cannot be bound to this type since it is a non-const reference.
In general, you cannot have a reference or a pointer to a bit-field because it has no address. A const reference works because it creates a temporary that is copy initialized with the value of the bit-field, and binds to that temporary instead.
You can indeed do an intermediate cast, like in your example or more explicitly like this:
fooVector.emplace_back(static_cast<uint32_t>(foo.foo1));
However, I am questioning why you want a 8-bit bitfield of a uint32_t
instead of just using a uint8_t
.