sean
sean

Reputation: 1822

How to cast vector<int> to int*

I have to maintain a program that nobody has touched since 2004.

class CSolver
{  
 ...  
 ClauseIdx add_clause (int * lits, int n_lits);
}

void and2 (CSolver & solver)   
{  
vector <int> lits;  
...  
solver.add_clause(lits.begin(), lits.size());  
}

The compiler complains that:

error: no matching function for call to ‘CSolver::add_clause(__gnu_cxx::__normal_iterator<int*, std::vector<int, std::allocator<int> > >, size_t)’

I try to cast it

solver.add_clause((int*)lits.begin(), lits.size());

But there is still a complaint:

error: invalid cast from type ‘__gnu_cxx::__normal_iterator<int*, std::vector<int, std::allocator<int> > >’ to type ‘int*’

I want to look for a quick fix on this, because changing interface of CSolver will result changing the whole program.

Thanks in advance.

Upvotes: 4

Views: 3130

Answers (5)

g24l
g24l

Reputation: 3125

Not so fast dear. Of course you can apply the solution already expressed by others:

solver.add_clause(lits.data(), lits.size());

or my preferred choice :

solver.add_clause(&lits[0], lits.size());

which designates that something uncommon goes on here,

but you should first consider that even if the standard defines that vector internal storage should be contiguous , this does not mean it is not reallocatable. Unfortunately the latter happens quite often.

Upvotes: 0

BigTailWolf
BigTailWolf

Reputation: 1028

You can just use like this to avoid of casting:

solver.add_clause(&(*lits.begin()), lits.size())

Here, take the *list.begin() and get its address, the address is a int *

Upvotes: 2

AJG85
AJG85

Reputation: 16187

This should work on multiple platforms without C++11 support:

solver.add_clause(&lits[0], lits.size());

Edit: The assumptions here being you just want to satisfy the API and you have resized the vector to have enough ints allocated for the operation and that the add_clause method is not going to muck with pointers, allocate new integers, or otherwise violate the heap.

The reason for this workaround being possible is due to the vector's internal contiguous allocation on the heap so a pointer to the first element is sufficient to use the container as an array for c-style iteration of elements as long as you note the amount of elements.

Upvotes: 4

tomahh
tomahh

Reputation: 13651

If you can compile against c++11, you can use

solver.add_clause(lits.data(), lits.size());

http://en.cppreference.com/w/cpp/container/vector/data

Upvotes: 7

GManNickG
GManNickG

Reputation: 503775

Like this:

solver.add_clause(lits.data(), lits.size());

Don't add casts without understanding what you're doing.

The function wants an array of ints, and it's asking for them by a pointer to the first element along with a size. This is a common C convention.

Lucky for us, std::vector stores elements precisely as a contiguous array, so we can get a pointer to the first element (lits.data(), &lits[0], &lits.front(), etc.) and then just pass the size.

Upvotes: 11

Related Questions