Bool vector reference

J

juraj

I'm trying to pass a member of a vector<bool> to my function by reference.
G++ complains:

invalid initialization of non-const reference of type 'bool&' from a
temporary of type 'std::_Bit_reference'

How to do it? The only way I managed to do it is to template a function
which takes pointers, however, the compiler issues a suspicious warning
"taking address of temporary...". Is there a cleaner way to do it?

TIA
 
E

Erik Wikström

I'm trying to pass a member of a vector<bool> to my function by reference.
G++ complains:

invalid initialization of non-const reference of type 'bool&' from a
temporary of type 'std::_Bit_reference'

You mean you are trying to pass an element from vector<bool> to a
function that takes a reference to a bool? It seems you have been bitten
by the fact that vector<bool> is a specialisation and the values
returned from operator[] and at() are not bools, but rather a wrapper
around a value. Change the function to take a bool and not a reference.
 
J

juraj

You mean you are trying to pass an element from vector<bool> to a
function that takes a reference to a bool?

Yes. Exactly.
It seems you have been bitten by the fact that vector<bool> is a specialisation
and the values returned from operator[] and at() are not bools, but rather a
wrapper around a value. Change the function to take a bool and not a reference.

Actually, I was passing two bools, and I needed them both modified outside
the function.

As I said, I got the following example with pointers to work, although the
compiler issued a warning ("taking address of temporary"), and I feel it's
unsafe because of that. Is this dangerous to do?

#include <vector>
using namespace std;

void myboolOR(boolpointer *first, boolpointer *second){
if(*first || *second) *first=*second=true; }

int main() {
vector<bool> myVector(4, 0); // 0000

myVector[1]=true; // 0100

myboolOR(&myVector[1], &myVector[2]); // 0110

}

The only other thing on my mind is to declare two temporary bools in the
main function, assign the values from the bools vector to them, call the
function on them, and assign their values back to the bools in vector.
However, this way I can end up with even messier code than the one I've
tried to simplify by writing the function.
 
A

Alf P. Steinbach

* juraj:
You mean you are trying to pass an element from vector<bool> to a
function that takes a reference to a bool?

Yes. Exactly.
It seems you have been bitten by the fact that vector<bool> is a specialisation
and the values returned from operator[] and at() are not bools, but rather a
wrapper around a value. Change the function to take a bool and not a reference.

Actually, I was passing two bools, and I needed them both modified outside
the function.

As I said, I got the following example with pointers to work, although the
compiler issued a warning ("taking address of temporary"), and I feel it's
unsafe because of that. Is this dangerous to do?
Yes.


#include <vector>
using namespace std;

void myboolOR(boolpointer *first, boolpointer *second){
if(*first || *second) *first=*second=true; }

This will not compile.

It's a good idea to post actual code.

int main() {
vector<bool> myVector(4, 0); // 0000

myVector[1]=true; // 0100

myboolOR(&myVector[1], &myVector[2]); // 0110

}

The only other thing on my mind is to declare two temporary bools in the
main function, assign the values from the bools vector to them, call the
function on them, and assign their values back to the bools in vector.
However, this way I can end up with even messier code than the one I've
tried to simplify by writing the function.

You can do e.g.

<code>
#include <vector>

// I/O:
#include <iostream>
#include <ostream>
#include <iterator>
#include <algorithm>

typedef std::vector<bool>::reference BoolRef;

void myboolOR( BoolRef first, BoolRef second)
{
if( first || second ) { first = second = true; }
}

int main()
{
using namespace std;

vector<bool> myVector( 4 ); // 0000

myVector[1] = true; // 0100

myboolOR( myVector[1], myVector[2] ); // 0110

copy(
myVector.begin(), myVector.end(),
ostream_iterator<bool>( cout )
);
cout << endl;
}
</code>

std::vector<bool>::reference also has a handy flip() member function.

However, the whole std::vector<bool> class is just an example of the
evils of premature optimization.


Cheers, & hth.,

- Alf
 
J

juraj

This will not compile.

Oops, I forgot the template declaration in front of the function prototype:

template<class boolpointer>
void myboolOR...

Otherwise, it compiles, and works fine on my compiler... I just wonder if
it is implementation independent. I guess it's not, since you've said that
it's dangerous to do it.

By the way, I'm interested why it isn't a good idea to do this. Speaking of
std::vector said:
typedef std::vector<bool>::reference BoolRef;

Thanks a lot! Now that's what I was looking for.
 
A

Alf P. Steinbach

* juraj:
Oops, I forgot the template declaration in front of the function prototype:

template<class boolpointer>
void myboolOR...

Otherwise, it compiles, and works fine on my compiler... I just wonder if
it is implementation independent. I guess it's not, since you've said that
it's dangerous to do it.

By the way, I'm interested why it isn't a good idea to do this. Speaking of
std::vector<bool>'s internals, what is the worst that can happen?

If by "this" you mean forcing a std::vector<bool>::reference into a
bool* in some way, what happens is that however you do it you dont' get
a pointer to a bool inside the vector, because there isn't one.


Cheers, & hth.,

- Alf
 
J

Jeff Schwab

juraj said:
I'm trying to pass a member of a vector<bool> to my function by reference.
G++ complains:

invalid initialization of non-const reference of type 'bool&' from a
temporary of type 'std::_Bit_reference'

How to do it? The only way I managed to do it is to template a function
which takes pointers, however, the compiler issues a suspicious warning
"taking address of temporary...". Is there a cleaner way to do it?

Try std::deque<bool> instead of std::vector<bool>.
 
P

Paul Brettschneider

Jeff said:
Try std::deque<bool> instead of std::vector<bool>.

Or simply use std::vector<char> instead of std::vector<bool>. Apparently
juraj uses template functions to access his vector anyway...
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,997
Messages
2,570,239
Members
46,827
Latest member
DMUK_Beginner

Latest Threads

Top