6

I have a class which stores an array and I need to write a method to return a pointer to that array so that other objects can access/modify it.

In an old version of my program, I did that by defining the array in C style. I.e, having a private element bool* list and then allocating memory in the constructor (and liberating that in the destructor). The method then was very simple:

bool* MyClass::getList() {
    return list;
}

Now, I have decided to rewrite the code and use std::vector<bool> instead of the classical array. The problem is that I have also modified the above method as:

bool* MyClass::getList() {
    return &(list[0]);
}

which seems to be the standard way of converting a C++ vector to C array. However, I cannot compile my code, I get the following error:

error: taking address of temporary [-fpermissive]
error: cannot convert ‘std::vector<bool>::reference* {aka std::_Bit_reference*}’ to ‘bool*’ in return

Could anyone help me out with this and tell me what shall I do?

(I have also read that another alternative is to use list.data() as the pointer but this would work only with the newest version of C++ compilers. I am not sure if this is a good idea or not).

Thanks,

MikeL
  • 2,369
  • 2
  • 24
  • 38
  • 6
    Remember that `std::vector` is a specialization of `std::vector`, which doesn't work *quite* like a normal vector. See e.g. [this reference](http://en.cppreference.com/w/cpp/container/vector_bool). – Some programmer dude Aug 15 '13 at 12:44
  • Oh! Thanks for your remark. I guess the problem is that it does not necessarily store its data in a single contiguous chunk of memory. So what is the solution? (In principle, I am not insisting on using a pointer (`bool*`) as the interface for accessing the list. I just thought this would require least modifications on the other parts of the code). – MikeL Aug 15 '13 at 12:48
  • You can always allocate a new "array" on the heap, copy from the vector to the array, and return the array. But then the caller have to free the array. – Some programmer dude Aug 15 '13 at 12:54
  • Thanks, but as the list is quite big I don't want to waste time on copying. – MikeL Aug 15 '13 at 13:30
  • It's just a [single function call](http://en.cppreference.com/w/cpp/algorithm/copy). And it's only going to be noticeable if you have more than several hundred of thousands of entries in the vector. – Some programmer dude Aug 15 '13 at 13:51
  • Yes, but the function could be called thousands of times and the list contains thousands of entries. – MikeL Aug 15 '13 at 15:57

4 Answers4

7

Your course of thinking is right in general and taking a pointer of the first element would have been sufficient. However, std::vector<bool> is not really a vector of bools as it is being implemented as a bit set. There is a general consensus among the C++ Standard Committee and the Library Working Group that vector<bool> should be deprecated and subsequently removed from the standard library, while the functionality will be reintroduced under a different name. But for now it is still there.

Getting back to your problem, you cannot really interpret a bitset as array of booleans. Therefore, there are two possible ways to go about this:

  1. Replace std::vector<bool> with one of the alternatives that would give you the right behavior.
  2. Convert std::vector<bool> to a C array manually when you need it. For example, you can use size() to pre-allocate memory, then iterate over a vector and fill our your array.

Hope it helps. Good Luck!

Community
  • 1
  • 1
4
bool* MyClass::getList() {
    return &(list[0]);
}

This will work with any type, but std::vector<bool> has special implementation, where 8 elements are stored in 1 byte, so it doesn't seem possible to take raw pointer to it.

Michael Kohne
  • 11,888
  • 3
  • 47
  • 79
Evgeny Eltishev
  • 593
  • 3
  • 18
0

try string.copy():

bool array[100];
std::vector<bool>;
std::copy(vector.begin(), vector.end(), array);
0

std::vector<bool> uses an internal model where each bool is stored as a single bit. This means it's not a plain C array internally as you would like and you can't convert it to one effortlessly.

Either replace std::vector<bool> with std::deque<bool> and don't use the deque parts, this will give the expected behaviour.

The other solution is to use a std::vector<char> instead and treat the values as bools. This will give the expected behaviour as long as you cast the values properly when accessing it.

Hampus Nilsson
  • 6,692
  • 1
  • 25
  • 29